diff options
| author | Veikka Tuominen <git@vexu.eu> | 2022-10-08 15:29:05 +0300 |
|---|---|---|
| committer | Veikka Tuominen <git@vexu.eu> | 2022-10-08 16:58:54 +0300 |
| commit | 3ccd4907fbcd04ecddffb618a4b14581fd080279 (patch) | |
| tree | 7db5554b1f8b2dcb5cef2fd4277d496d35ca385b | |
| parent | b5c0a797a7f816e502129ad42d5bf19ff84b45e0 (diff) | |
| download | zig-3ccd4907fbcd04ecddffb618a4b14581fd080279.tar.gz zig-3ccd4907fbcd04ecddffb618a4b14581fd080279.zip | |
Sema: add error for capturing a runtime value outside of function scope
Closes #13104
| -rw-r--r-- | src/Sema.zig | 32 | ||||
| -rw-r--r-- | test/cases/compile_errors/accessing_runtime_paramter_outside_function_scope.zig | 12 |
2 files changed, 42 insertions, 2 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 32ea08f697..e429d5368a 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -14357,7 +14357,7 @@ fn zirClosureCapture( // value only. In such case we preserve the type and use a dummy runtime value. const operand = try sema.resolveInst(inst_data.operand); const val = (try sema.resolveMaybeUndefValAllowVariables(block, src, operand)) orelse - Value.initTag(.generic_poison); + Value.initTag(.unreachable_value); try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, .{ .ty = try sema.typeOf(operand).copy(sema.perm_arena), @@ -14394,7 +14394,35 @@ 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) { + if (tv.val.tag() == .unreachable_value and !block.is_typeof 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 outside function scope", .{some}) + else + try sema.errMsg(block, inst_data.src(), "variable not accessible outside function scope", .{}); + errdefer msg.destroy(sema.gpa); + + // TODO add "declared here" note + break :msg msg; + }; + return sema.failWithOwnedErrorMsg(msg); + } + + if (tv.val.tag() == .unreachable_value and !block.is_typeof and !block.is_comptime and sema.func != null) { const msg = msg: { const name = name: { const file = sema.owner_decl.getFileScope(); diff --git a/test/cases/compile_errors/accessing_runtime_paramter_outside_function_scope.zig b/test/cases/compile_errors/accessing_runtime_paramter_outside_function_scope.zig new file mode 100644 index 0000000000..583b7128c7 --- /dev/null +++ b/test/cases/compile_errors/accessing_runtime_paramter_outside_function_scope.zig @@ -0,0 +1,12 @@ +export fn entry(y: u8) void { + const Thing = struct { + y: u8 = y, + }; + _ = @sizeOf(Thing); +} + +// error +// backend=stage2 +// target=native +// +// :3:17: error: 'y' not accessible outside function scope |
