Commit 6547c3887e

Veikka Tuominen <git@vexu.eu>
2022-08-02 18:03:38
Sema: add error for closure capture at runtime
1 parent fa321a0
Changed files (2)
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);
 }
 
test/cases/compile_errors/stage1/obj/accessing_runtime_parameter_from_outer_function.zig → 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