authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-05-26 13:07:51+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-05-27 10:29:15+03:00
loge08cdad53b25876b247322aed91257288e8b9230
treee212a7b592d0344ea80d730aca4df14135e4747d
parent92c4e4f2c234816a70472250702f834a1842f4e6

Sema: add error for runtime indexing comptime array


2 files changed, 72 insertions(+), 1 deletions(-)

src/Sema.zig+41-1
......@@ -7309,9 +7309,11 @@ fn zirElemVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
73097309 defer tracy.end();
73107310
73117311 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
7312 const src = sema.src; // TODO better source location
7313 const elem_index_src = sema.src; // TODO better source location
73127314 const array = try sema.resolveInst(bin_inst.lhs);
73137315 const elem_index = try sema.resolveInst(bin_inst.rhs);
7314 return sema.elemVal(block, sema.src, array, elem_index, sema.src);
7316 return sema.elemVal(block, src, array, elem_index, elem_index_src);
73157317}
73167318
73177319fn zirElemValNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -18473,6 +18475,25 @@ fn elemValArray(
1847318475 }
1847418476 }
1847518477
18478 const valid_rt = try sema.validateRunTimeType(block, elem_index_src, elem_ty, false);
18479 if (!valid_rt) {
18480 const msg = msg: {
18481 const msg = try sema.errMsg(
18482 block,
18483 elem_index_src,
18484 "values of type '{}' must be comptime known, but index value is runtime known",
18485 .{array_ty.fmt(sema.mod)},
18486 );
18487 errdefer msg.destroy(sema.gpa);
18488
18489 const src_decl = sema.mod.declPtr(block.src_decl);
18490 try sema.explainWhyTypeIsComptime(block, elem_index_src, msg, array_src.toSrcLoc(src_decl), array_ty);
18491
18492 break :msg msg;
18493 };
18494 return sema.failWithOwnedErrorMsg(block, msg);
18495 }
18496
1847618497 const runtime_src = if (maybe_undef_array_val != null) elem_index_src else array_src;
1847718498 try sema.requireRuntimeBlock(block, runtime_src);
1847818499 if (block.wantSafety()) {
......@@ -18528,6 +18549,25 @@ fn elemPtrArray(
1852818549 }
1852918550 }
1853018551
18552 const valid_rt = try sema.validateRunTimeType(block, elem_index_src, array_ty.elemType2(), false);
18553 if (!valid_rt) {
18554 const msg = msg: {
18555 const msg = try sema.errMsg(
18556 block,
18557 elem_index_src,
18558 "values of type '{}' must be comptime known, but index value is runtime known",
18559 .{array_ty.fmt(sema.mod)},
18560 );
18561 errdefer msg.destroy(sema.gpa);
18562
18563 const src_decl = sema.mod.declPtr(block.src_decl);
18564 try sema.explainWhyTypeIsComptime(block, elem_index_src, msg, array_ptr_src.toSrcLoc(src_decl), array_ty);
18565
18566 break :msg msg;
18567 };
18568 return sema.failWithOwnedErrorMsg(block, msg);
18569 }
18570
1853118571 const runtime_src = if (maybe_undef_array_ptr_val != null) elem_index_src else array_ptr_src;
1853218572 try sema.requireRuntimeBlock(block, runtime_src);
1853318573 if (block.wantSafety()) {
test/cases/compile_errors/runtime_indexing_comptime_array.zig created+31
......@@ -0,0 +1,31 @@
1fn foo() void {}
2fn bar() void {}
3
4pub export fn entry1() void {
5 const TestFn = fn () void;
6 const test_fns = [_]TestFn{ foo, bar };
7 for (test_fns) |testFn| {
8 testFn();
9 }
10}
11pub export fn entry2() void {
12 const TestFn = fn () void;
13 const test_fns = [_]TestFn{ foo, bar };
14 var i: usize = 0;
15 _ = test_fns[i];
16}
17pub export fn entry3() void {
18 const TestFn = fn () void;
19 const test_fns = [_]TestFn{ foo, bar };
20 var i: usize = 0;
21 _ = &test_fns[i];
22}
23// error
24// backend=stage2,llvm
25//
26// :6:33: error: values of type '[2]fn() callconv(.C) void' must be comptime known, but index value is runtime known
27// :6:33: note: use '*const fn() callconv(.C) void' for a function pointer type
28// :13:33: error: values of type '[2]fn() callconv(.C) void' must be comptime known, but index value is runtime known
29// :13:33: note: use '*const fn() callconv(.C) void' for a function pointer type
30// :19:33: error: values of type '[2]fn() callconv(.C) void' must be comptime known, but index value is runtime known
31// :19:33: note: use '*const fn() callconv(.C) void' for a function pointer type