authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-08-02 19:03:38+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-08-03 16:45:33+03:00
log6547c3887eb604cf4d494d307927a50a12117708
tree0a3c18111e45c30a1e045028fc672ff3bca7553c
parentfa321a07cd985c672879c091db6dd0aa6b66f0b7

Sema: add error for closure capture at runtime


3 files changed, 50 insertions(+), 21 deletions(-)

src/Sema.zig+30
...@@ -13143,6 +13143,36 @@ fn zirClosureGet(...@@ -13143,6 +13143,36 @@ fn zirClosureGet(
13143 scope = scope.parent.?;13143 scope = scope.parent.?;
13144 } else unreachable;13144 } else unreachable;
1314513145
13146 if (tv.val.tag() == .generic_poison and !block.is_typeof and !block.is_comptime and sema.func != null) {
13147 const msg = msg: {
13148 const name = name: {
13149 const file = sema.owner_decl.getFileScope();
13150 const tree = file.getTree(sema.mod.gpa) catch |err| {
13151 // In this case we emit a warning + a less precise source location.
13152 log.warn("unable to load {s}: {s}", .{
13153 file.sub_file_path, @errorName(err),
13154 });
13155 break :name null;
13156 };
13157 const node = sema.owner_decl.relativeToNodeIndex(inst_data.src_node);
13158 const token = tree.nodes.items(.main_token)[node];
13159 break :name tree.tokenSlice(token);
13160 };
13161
13162 const msg = if (name) |some|
13163 try sema.errMsg(block, inst_data.src(), "'{s}' not accessible from inner function", .{some})
13164 else
13165 try sema.errMsg(block, inst_data.src(), "variable not accessible from inner function", .{});
13166 errdefer msg.destroy(sema.gpa);
13167
13168 try sema.errNote(block, LazySrcLoc.nodeOffset(0), msg, "crossed function definition here", .{});
13169
13170 // TODO add "declared here" note
13171 break :msg msg;
13172 };
13173 return sema.failWithOwnedErrorMsg(block, msg);
13174 }
13175
13146 return sema.addConstant(tv.ty, tv.val);13176 return sema.addConstant(tv.ty, tv.val);
13147}13177}
1314813178
test/cases/compile_errors/accessing_runtime_parameter_from_outer_function.zig created+20
...@@ -0,0 +1,20 @@
1fn outer(y: u32) *const fn (u32) u32 {
2 const st = struct {
3 fn get(z: u32) u32 {
4 return z + y;
5 }
6 };
7 return st.get;
8}
9export fn entry() void {
10 var func = outer(10);
11 var x = func(3);
12 _ = x;
13}
14
15// error
16// backend=stage2
17// target=native
18//
19// :4:24: error: 'y' not accessible from inner function
20// :3:9: note: crossed function definition here
test/cases/compile_errors/stage1/obj/accessing_runtime_parameter_from_outer_function.zig deleted-21
...@@ -1,21 +0,0 @@
1fn outer(y: u32) fn (u32) u32 {
2 const st = struct {
3 fn get(z: u32) u32 {
4 return z + y;
5 }
6 };
7 return st.get;
8}
9export fn entry() void {
10 var func = outer(10);
11 var x = func(3);
12 _ = x;
13}
14
15// error
16// backend=stage1
17// target=native
18//
19// tmp.zig:4:24: error: 'y' not accessible from inner function
20// tmp.zig:3:28: note: crossed function definition here
21// tmp.zig:1:10: note: declared here