authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-01 16:08:35+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-07 10:50:05+03:00
log299836dbd94dd9af25b8485f58ba611b62909d54
tree662b42d9b5aa0e83c3e4bb611945e273c4e240b2
parent252388eb28fde40f085e14cd341efdc701093fe1

Sema: panic at comptime + misc error message improvements


25 files changed, 243 insertions(+), 204 deletions(-)

src/AstGen.zig+2-1
......@@ -2464,6 +2464,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
24642464 .repeat,
24652465 .repeat_inline,
24662466 .panic,
2467 .panic_comptime,
24672468 => {
24682469 noreturn_src_node = statement;
24692470 break :b true;
......@@ -7358,7 +7359,7 @@ fn builtinCall(
73587359 .bool_to_int => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .bool_to_int),
73597360 .embed_file => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .embed_file),
73607361 .error_name => return simpleUnOp(gz, scope, rl, node, .{ .ty = .anyerror_type }, params[0], .error_name),
7361 .panic => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .panic),
7362 .panic => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], if (gz.force_comptime) .panic_comptime else .panic),
73627363 .set_cold => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .set_cold),
73637364 .set_runtime_safety => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .set_runtime_safety),
73647365 .sqrt => return simpleUnOp(gz, scope, rl, node, .none, params[0], .sqrt),
src/Sema.zig+43-6
......@@ -903,7 +903,8 @@ fn analyzeBodyInner(
903903 .ret_load => break sema.zirRetLoad(block, inst),
904904 .ret_err_value => break sema.zirRetErrValue(block, inst),
905905 .@"unreachable" => break sema.zirUnreachable(block, inst),
906 .panic => break sema.zirPanic(block, inst),
906 .panic => break sema.zirPanic(block, inst, false),
907 .panic_comptime => break sema.zirPanic(block, inst, true),
907908 // zig fmt: on
908909
909910 .extended => ext: {
......@@ -3870,10 +3871,26 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
38703871 .Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(sema.mod)}),
38713872 }
38723873
3874 const elem_ty = operand_ty.elemType2();
38733875 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {
38743876 if (val.isUndef()) {
38753877 return sema.fail(block, src, "cannot dereference undefined value", .{});
38763878 }
3879 } else if (!(try sema.validateRunTimeType(block, src, elem_ty, false))) {
3880 const msg = msg: {
3881 const msg = try sema.errMsg(
3882 block,
3883 src,
3884 "values of type '{}' must be comptime known, but operand value is runtime known",
3885 .{elem_ty.fmt(sema.mod)},
3886 );
3887 errdefer msg.destroy(sema.gpa);
3888
3889 const src_decl = sema.mod.declPtr(block.src_decl);
3890 try sema.explainWhyTypeIsComptime(block, src, msg, src.toSrcLoc(src_decl), elem_ty);
3891 break :msg msg;
3892 };
3893 return sema.failWithOwnedErrorMsg(block, msg);
38773894 }
38783895}
38793896
......@@ -4308,11 +4325,15 @@ fn zirCompileLog(
43084325 return Air.Inst.Ref.void_value;
43094326}
43104327
4311fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {
4328fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index, force_comptime: bool) CompileError!Zir.Inst.Index {
43124329 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
4313 const src: LazySrcLoc = inst_data.src();
4330 const src = inst_data.src();
43144331 const msg_inst = try sema.resolveInst(inst_data.operand);
43154332
4333 if (block.is_comptime or force_comptime) {
4334 return sema.fail(block, src, "encountered @panic at comptime", .{});
4335 }
4336 try sema.requireRuntimeBlock(block, src);
43164337 return sema.panicWithMsg(block, src, msg_inst);
43174338}
43184339
......@@ -8357,7 +8378,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
83578378 return sema.fail(
83588379 block,
83598380 src,
8360 "switch must handle all possibilities",
8381 "else prong required when switching on type 'anyerror'",
83618382 .{},
83628383 );
83638384 }
......@@ -17416,7 +17437,7 @@ fn zirVarExtended(
1741617437 const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand);
1741717438 const src = sema.src;
1741817439 const ty_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at type
17419 const mut_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at mut token
17440 const name_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at the name token
1742017441 const init_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at init expr
1742117442 const small = @bitCast(Zir.Inst.ExtendedVar.Small, extended.small);
1742217443
......@@ -17460,7 +17481,7 @@ fn zirVarExtended(
1746017481 return sema.failWithNeededComptime(block, init_src);
1746117482 } else Value.initTag(.unreachable_value);
1746217483
17463 try sema.validateVarType(block, mut_src, var_ty, small.is_extern);
17484 try sema.validateVarType(block, name_src, var_ty, small.is_extern);
1746417485
1746517486 const new_var = try sema.gpa.create(Module.Var);
1746617487 errdefer sema.gpa.destroy(new_var);
......@@ -17957,6 +17978,9 @@ fn validateVarType(
1795717978
1795817979 const src_decl = mod.declPtr(block.src_decl);
1795917980 try sema.explainWhyTypeIsComptime(block, src, msg, src.toSrcLoc(src_decl), var_ty);
17981 if (var_ty.zigTypeTag() == .ComptimeInt or var_ty.zigTypeTag() == .ComptimeFloat) {
17982 try sema.errNote(block, src, msg, "to modify this variable at runtime, it must be given an explicit fixed-size number type", .{});
17983 }
1796017984
1796117985 break :msg msg;
1796217986 };
......@@ -20041,6 +20065,15 @@ fn coerce(
2004120065 });
2004220066 return sema.addConstant(dest_ty, slice_val);
2004320067 }
20068
20069 if (inst_ty.zigTypeTag() == .Array) {
20070 return sema.fail(
20071 block,
20072 inst_src,
20073 "array literal requires address-of operator (&) to coerce to slice type '{}'",
20074 .{dest_ty.fmt(sema.mod)},
20075 );
20076 }
2004420077 },
2004520078 .Many => p: {
2004620079 if (!inst_ty.isSlice()) break :p;
......@@ -24433,6 +24466,10 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
2443324466 } else {
2443424467 // The provided type is the enum tag type.
2443524468 union_obj.tag_ty = try provided_ty.copy(decl_arena_allocator);
24469 if (union_obj.tag_ty.zigTypeTag() != .Enum) {
24470 const tag_ty_src = src; // TODO better source location
24471 return sema.fail(block, tag_ty_src, "expected enum tag type, found '{}'", .{union_obj.tag_ty.fmt(sema.mod)});
24472 }
2443624473 // The fields of the union must match the enum exactly.
2443724474 // Store a copy of the enum field names so we can check for
2443824475 // missing or extraneous fields later.
src/Zir.zig+5
......@@ -798,6 +798,8 @@ pub const Inst = struct {
798798 error_name,
799799 /// Implement builtin `@panic`. Uses `un_node`.
800800 panic,
801 /// Same as `panic` but forces comptime.
802 panic_comptime,
801803 /// Implement builtin `@setCold`. Uses `un_node`.
802804 set_cold,
803805 /// Implement builtin `@setRuntimeSafety`. Uses `un_node`.
......@@ -1260,6 +1262,7 @@ pub const Inst = struct {
12601262 .repeat,
12611263 .repeat_inline,
12621264 .panic,
1265 .panic_comptime,
12631266 => true,
12641267 };
12651268 }
......@@ -1533,6 +1536,7 @@ pub const Inst = struct {
15331536 .repeat,
15341537 .repeat_inline,
15351538 .panic,
1539 .panic_comptime,
15361540 .@"try",
15371541 .try_ptr,
15381542 //.try_inline,
......@@ -1726,6 +1730,7 @@ pub const Inst = struct {
17261730 .embed_file = .un_node,
17271731 .error_name = .un_node,
17281732 .panic = .un_node,
1733 .panic_comptime = .un_node,
17291734 .set_cold = .un_node,
17301735 .set_runtime_safety = .un_node,
17311736 .sqrt = .un_node,
src/print_zir.zig+1
......@@ -197,6 +197,7 @@ const Writer = struct {
197197 .embed_file,
198198 .error_name,
199199 .panic,
200 .panic_comptime,
200201 .set_cold,
201202 .set_runtime_safety,
202203 .sqrt,
test/cases/compile_errors/method_call_with_first_arg_type_primitive.zig created+21
......@@ -0,0 +1,21 @@
1const Foo = struct {
2 x: i32,
3
4 fn init(x: i32) Foo {
5 return Foo {
6 .x = x,
7 };
8 }
9};
10
11export fn f() void {
12 const derp = Foo.init(3);
13
14 derp.init();
15}
16
17// error
18// backend=stage2
19// target=native
20//
21// :14:9: error: type 'tmp.Foo' has no field or member function named 'init'
test/cases/compile_errors/method_call_with_first_arg_type_wrong_container.zig created+30
......@@ -0,0 +1,30 @@
1pub const List = struct {
2 len: usize,
3 allocator: *Allocator,
4
5 pub fn init(allocator: *Allocator) List {
6 return List {
7 .len = 0,
8 .allocator = allocator,
9 };
10 }
11};
12
13pub var global_allocator = Allocator {
14 .field = 1234,
15};
16
17pub const Allocator = struct {
18 field: i32,
19};
20
21export fn foo() void {
22 var x = List.init(&global_allocator);
23 x.init();
24}
25
26// error
27// backend=llvm
28// target=native
29//
30// :23:6: error: type 'tmp.List' has no field or member function named 'init'
test/cases/compile_errors/missing_const_in_slice_with_nested_array_type.zig created+18
......@@ -0,0 +1,18 @@
1const Geo3DTex2D = struct { vertices: [][2]f32 };
2pub fn getGeo3DTex2D() Geo3DTex2D {
3 return Geo3DTex2D{
4 .vertices = [_][2]f32{
5 [_]f32{ -0.5, -0.5},
6 },
7 };
8}
9export fn entry() void {
10 var geo_data = getGeo3DTex2D();
11 _ = geo_data;
12}
13
14// error
15// backend=llvm
16// target=native
17//
18// :4:30: error: array literal requires address-of operator (&) to coerce to slice type '[][2]f32'
test/cases/compile_errors/mul_overflow_in_function_evaluation.zig created+14
......@@ -0,0 +1,14 @@
1const y = mul(300, 6000);
2fn mul(a: u16, b: u16) u16 {
3 return a * b;
4}
5
6export fn entry() usize { return @sizeOf(@TypeOf(&y)); }
7
8// error
9// backend=stage2
10// target=native
11//
12// :3:14: error: overflow of integer type 'u16' with value '1800000'
13// :1:14: note: called from here
14
test/cases/compile_errors/negation_overflow_in_function_evaluation.zig created+13
......@@ -0,0 +1,13 @@
1const y = neg(-128);
2fn neg(x: i8) i8 {
3 return -x;
4}
5
6export fn entry() usize { return @sizeOf(@TypeOf(&y)); }
7
8// error
9// backend=stage2
10// target=native
11//
12// :3:12: error: overflow of integer type 'i8' with value '128'
13// :1:14: note: called from here
test/cases/compile_errors/no_else_prong_on_switch_on_global_error_set.zig created+14
......@@ -0,0 +1,14 @@
1export fn entry() void {
2 foo(error.A);
3}
4fn foo(a: anyerror) void {
5 switch (a) {
6 error.A => {},
7 }
8}
9
10// error
11// backend=stage2
12// target=native
13//
14// :5:5: error: else prong required when switching on type 'anyerror'
test/cases/compile_errors/non-const_variables_of_things_that_require_const_variables.zig created+44
......@@ -0,0 +1,44 @@
1export fn entry1() void {
2 var m2 = &2;
3 _ = m2;
4}
5export fn entry2() void {
6 var a = undefined;
7 _ = a;
8}
9export fn entry3() void {
10 var b = 1;
11 _ = b;
12}
13export fn entry4() void {
14 var c = 1.0;
15 _ = c;
16}
17export fn entry5() void {
18 var d = null;
19 _ = d;
20}
21export fn entry6(opaque_: *Opaque) void {
22 var e = opaque_.*;
23 _ = e;
24}
25export fn entry7() void {
26 var f = i32;
27 _ = f;
28}
29const Opaque = opaque {};
30
31// error
32// backend=stage2
33// target=native
34//
35// :2:8: error: variable of type '*const comptime_int' must be const or comptime
36// :6:8: error: variable of type '@TypeOf(undefined)' must be const or comptime
37// :10:8: error: variable of type 'comptime_int' must be const or comptime
38// :10:8: note: to modify this variable at runtime, it must be given an explicit fixed-size number type
39// :14:8: error: variable of type 'comptime_float' must be const or comptime
40// :14:8: note: to modify this variable at runtime, it must be given an explicit fixed-size number type
41// :18:8: error: variable of type '@TypeOf(null)' must be const or comptime
42// :22:19: error: values of type 'tmp.Opaque' must be comptime known, but operand value is runtime known
43// :26:8: error: variable of type 'type' must be const or comptime
44// :26:8: note: types are not available at runtime
test/cases/compile_errors/non_error_sets_used_in_merge_error_sets_operator.zig created+15
......@@ -0,0 +1,15 @@
1export fn foo() void {
2 const Errors = u8 || u16;
3 _ = Errors;
4}
5export fn bar() void {
6 const Errors = error{} || u16;
7 _ = Errors;
8}
9
10// error
11// backend=stage2
12// target=native
13//
14// :2:20: error: expected error set type, found 'u8'
15// :6:31: error: expected error set type, found 'u16'
test/cases/compile_errors/panic_called_at_compile_time.zig created+11
......@@ -0,0 +1,11 @@
1export fn entry() void {
2 comptime {
3 @panic("aoeu",);
4 }
5}
6
7// error
8// backend=stage2
9// target=native
10//
11// :3:9: error: encountered @panic at comptime
test/cases/compile_errors/stage1/non_compile_time_array_concatenation.zig created+11
......@@ -0,0 +1,11 @@
1fn f() []u8 {
2 return s ++ "foo";
3}
4var s: [10]u8 = undefined;
5export fn entry() usize { return @sizeOf(@TypeOf(f)); }
6
7// error
8// backend=stage1
9// target=native
10//
11// tmp.zig:2:12: error: unable to evaluate constant expression
test/cases/compile_errors/stage1/obj/method_call_with_first_arg_type_primitive.zig deleted-21
......@@ -1,21 +0,0 @@
1const Foo = struct {
2 x: i32,
3
4 fn init(x: i32) Foo {
5 return Foo {
6 .x = x,
7 };
8 }
9};
10
11export fn f() void {
12 const derp = Foo.init(3);
13
14 derp.init();
15}
16
17// error
18// backend=stage1
19// target=native
20//
21// tmp.zig:14:5: error: expected type 'i32', found 'Foo'
test/cases/compile_errors/stage1/obj/method_call_with_first_arg_type_wrong_container.zig deleted-30
......@@ -1,30 +0,0 @@
1pub const List = struct {
2 len: usize,
3 allocator: *Allocator,
4
5 pub fn init(allocator: *Allocator) List {
6 return List {
7 .len = 0,
8 .allocator = allocator,
9 };
10 }
11};
12
13pub var global_allocator = Allocator {
14 .field = 1234,
15};
16
17pub const Allocator = struct {
18 field: i32,
19};
20
21export fn foo() void {
22 var x = List.init(&global_allocator);
23 x.init();
24}
25
26// error
27// backend=stage1
28// target=native
29//
30// tmp.zig:23:5: error: expected type '*Allocator', found '*List'
test/cases/compile_errors/stage1/obj/missing_const_in_slice_with_nested_array_type.zig deleted-18
......@@ -1,18 +0,0 @@
1const Geo3DTex2D = struct { vertices: [][2]f32 };
2pub fn getGeo3DTex2D() Geo3DTex2D {
3 return Geo3DTex2D{
4 .vertices = [_][2]f32{
5 [_]f32{ -0.5, -0.5},
6 },
7 };
8}
9export fn entry() void {
10 var geo_data = getGeo3DTex2D();
11 _ = geo_data;
12}
13
14// error
15// backend=stage1
16// target=native
17//
18// tmp.zig:4:30: error: array literal requires address-of operator (&) to coerce to slice type '[][2]f32'
test/cases/compile_errors/stage1/obj/mul_overflow_in_function_evaluation.zig deleted-12
......@@ -1,12 +0,0 @@
1const y = mul(300, 6000);
2fn mul(a: u16, b: u16) u16 {
3 return a * b;
4}
5
6export fn entry() usize { return @sizeOf(@TypeOf(y)); }
7
8// error
9// backend=stage1
10// target=native
11//
12// tmp.zig:3:14: error: operation caused overflow
test/cases/compile_errors/stage1/obj/negation_overflow_in_function_evaluation.zig deleted-12
......@@ -1,12 +0,0 @@
1const y = neg(-128);
2fn neg(x: i8) i8 {
3 return -x;
4}
5
6export fn entry() usize { return @sizeOf(@TypeOf(y)); }
7
8// error
9// backend=stage1
10// target=native
11//
12// tmp.zig:3:12: error: negation caused overflow
test/cases/compile_errors/stage1/obj/no_else_prong_on_switch_on_global_error_set.zig deleted-14
......@@ -1,14 +0,0 @@
1export fn entry() void {
2 foo(error.A);
3}
4fn foo(a: anyerror) void {
5 switch (a) {
6 error.A => {},
7 }
8}
9
10// error
11// backend=stage1
12// target=native
13//
14// tmp.zig:5:5: error: else prong required when switching on type 'anyerror'
test/cases/compile_errors/stage1/obj/non-const_variables_of_things_that_require_const_variables.zig deleted-51
......@@ -1,51 +0,0 @@
1export fn entry1() void {
2 var m2 = &2;
3 _ = m2;
4}
5export fn entry2() void {
6 var a = undefined;
7 _ = a;
8}
9export fn entry3() void {
10 var b = 1;
11 _ = b;
12}
13export fn entry4() void {
14 var c = 1.0;
15 _ = c;
16}
17export fn entry5() void {
18 var d = null;
19 _ = d;
20}
21export fn entry6(opaque_: *Opaque) void {
22 var e = opaque_.*;
23 _ = e;
24}
25export fn entry7() void {
26 var f = i32;
27 _ = f;
28}
29export fn entry8() void {
30 var h = (Foo {}).bar;
31 _ = h;
32}
33const Opaque = opaque {};
34const Foo = struct {
35 fn bar(self: *const Foo) void {_ = self;}
36};
37
38// error
39// backend=stage1
40// target=native
41//
42// tmp.zig:2:4: error: variable of type '*const comptime_int' must be const or comptime
43// tmp.zig:6:4: error: variable of type '@Type(.Undefined)' must be const or comptime
44// tmp.zig:10:4: error: variable of type 'comptime_int' must be const or comptime
45// tmp.zig:10:4: note: to modify this variable at runtime, it must be given an explicit fixed-size number type
46// tmp.zig:14:4: error: variable of type 'comptime_float' must be const or comptime
47// tmp.zig:14:4: note: to modify this variable at runtime, it must be given an explicit fixed-size number type
48// tmp.zig:18:4: error: variable of type '@Type(.Null)' must be const or comptime
49// tmp.zig:22:4: error: variable of type 'Opaque' not allowed
50// tmp.zig:26:4: error: variable of type 'type' must be const or comptime
51// tmp.zig:30:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime
test/cases/compile_errors/stage1/obj/non_compile_time_array_concatenation.zig deleted-11
......@@ -1,11 +0,0 @@
1fn f() []u8 {
2 return s ++ "foo";
3}
4var s: [10]u8 = undefined;
5export fn entry() usize { return @sizeOf(@TypeOf(f)); }
6
7// error
8// backend=stage1
9// target=native
10//
11// tmp.zig:2:12: error: unable to evaluate constant expression
test/cases/compile_errors/stage1/obj/non_error_sets_used_in_merge_error_sets_operator.zig deleted-17
......@@ -1,17 +0,0 @@
1export fn foo() void {
2 const Errors = u8 || u16;
3 _ = Errors;
4}
5export fn bar() void {
6 const Errors = error{} || u16;
7 _ = Errors;
8}
9
10// error
11// backend=stage1
12// target=native
13//
14// tmp.zig:2:20: error: expected error set type, found type 'u8'
15// tmp.zig:2:23: note: `||` merges error sets; `or` performs boolean OR
16// tmp.zig:6:31: error: expected error set type, found type 'u16'
17// tmp.zig:6:28: note: `||` merges error sets; `or` performs boolean OR
test/cases/compile_errors/stage1/obj/panic_called_at_compile_time.zig deleted-11
......@@ -1,11 +0,0 @@
1export fn entry() void {
2 comptime {
3 @panic("aoeu",);
4 }
5}
6
7// error
8// backend=stage1
9// target=native
10//
11// tmp.zig:3:9: error: encountered @panic at compile-time
test/cases/compile_errors/use_invalid_number_literal_as_array_index.zig+1
......@@ -9,3 +9,4 @@ export fn entry() void {
99// target=native
1010//
1111// :1:1: error: variable of type 'comptime_int' must be const or comptime
12// :1:1: note: to modify this variable at runtime, it must be given an explicit fixed-size number type