aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2022-08-02 19:03:38 +0300
committerVeikka Tuominen <git@vexu.eu>2022-08-03 16:45:33 +0300
commit6547c3887eb604cf4d494d307927a50a12117708 (patch)
tree0a3c18111e45c30a1e045028fc672ff3bca7553c
parentfa321a07cd985c672879c091db6dd0aa6b66f0b7 (diff)
downloadzig-6547c3887eb604cf4d494d307927a50a12117708.tar.gz
zig-6547c3887eb604cf4d494d307927a50a12117708.zip
Sema: add error for closure capture at runtime
-rw-r--r--src/Sema.zig30
-rw-r--r--test/cases/compile_errors/accessing_runtime_parameter_from_outer_function.zig (renamed from test/cases/compile_errors/stage1/obj/accessing_runtime_parameter_from_outer_function.zig)9
2 files changed, 34 insertions, 5 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index e41602a037..7b5a7cdf26 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -13143,6 +13143,36 @@ fn zirClosureGet(
scope = scope.parent.?;
} else unreachable;
+ if (tv.val.tag() == .generic_poison and !block.is_typeof and !block.is_comptime and sema.func != null) {
+ const msg = msg: {
+ const name = name: {
+ const file = sema.owner_decl.getFileScope();
+ const tree = file.getTree(sema.mod.gpa) catch |err| {
+ // In this case we emit a warning + a less precise source location.
+ log.warn("unable to load {s}: {s}", .{
+ file.sub_file_path, @errorName(err),
+ });
+ break :name null;
+ };
+ const node = sema.owner_decl.relativeToNodeIndex(inst_data.src_node);
+ const token = tree.nodes.items(.main_token)[node];
+ break :name tree.tokenSlice(token);
+ };
+
+ const msg = if (name) |some|
+ try sema.errMsg(block, inst_data.src(), "'{s}' not accessible from inner function", .{some})
+ else
+ try sema.errMsg(block, inst_data.src(), "variable not accessible from inner function", .{});
+ errdefer msg.destroy(sema.gpa);
+
+ try sema.errNote(block, LazySrcLoc.nodeOffset(0), msg, "crossed function definition here", .{});
+
+ // TODO add "declared here" note
+ break :msg msg;
+ };
+ return sema.failWithOwnedErrorMsg(block, msg);
+ }
+
return sema.addConstant(tv.ty, tv.val);
}
diff --git a/test/cases/compile_errors/stage1/obj/accessing_runtime_parameter_from_outer_function.zig b/test/cases/compile_errors/accessing_runtime_parameter_from_outer_function.zig
index 73a9e94d44..49ef3b4d4d 100644
--- a/test/cases/compile_errors/stage1/obj/accessing_runtime_parameter_from_outer_function.zig
+++ b/test/cases/compile_errors/accessing_runtime_parameter_from_outer_function.zig
@@ -1,4 +1,4 @@
-fn outer(y: u32) fn (u32) u32 {
+fn outer(y: u32) *const fn (u32) u32 {
const st = struct {
fn get(z: u32) u32 {
return z + y;
@@ -13,9 +13,8 @@ export fn entry() void {
}
// error
-// backend=stage1
+// backend=stage2
// target=native
//
-// tmp.zig:4:24: error: 'y' not accessible from inner function
-// tmp.zig:3:28: note: crossed function definition here
-// tmp.zig:1:10: note: declared here
+// :4:24: error: 'y' not accessible from inner function
+// :3:9: note: crossed function definition here