authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-10-08 15:29:05+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-10-08 16:58:54+03:00
log3ccd4907fbcd04ecddffb618a4b14581fd080279
tree7db5554b1f8b2dcb5cef2fd4277d496d35ca385b
parentb5c0a797a7f816e502129ad42d5bf19ff84b45e0

Sema: add error for capturing a runtime value outside of function scope

Closes #13104

2 files changed, 42 insertions(+), 2 deletions(-)

src/Sema.zig+30-2
...@@ -14357,7 +14357,7 @@ fn zirClosureCapture(...@@ -14357,7 +14357,7 @@ fn zirClosureCapture(
14357 // value only. In such case we preserve the type and use a dummy runtime value.14357 // value only. In such case we preserve the type and use a dummy runtime value.
14358 const operand = try sema.resolveInst(inst_data.operand);14358 const operand = try sema.resolveInst(inst_data.operand);
14359 const val = (try sema.resolveMaybeUndefValAllowVariables(block, src, operand)) orelse14359 const val = (try sema.resolveMaybeUndefValAllowVariables(block, src, operand)) orelse
14360 Value.initTag(.generic_poison);14360 Value.initTag(.unreachable_value);
1436114361
14362 try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, .{14362 try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, .{
14363 .ty = try sema.typeOf(operand).copy(sema.perm_arena),14363 .ty = try sema.typeOf(operand).copy(sema.perm_arena),
...@@ -14394,7 +14394,35 @@ fn zirClosureGet(...@@ -14394,7 +14394,35 @@ fn zirClosureGet(
14394 scope = scope.parent.?;14394 scope = scope.parent.?;
14395 } else unreachable;14395 } else unreachable;
1439614396
14397 if (tv.val.tag() == .generic_poison and !block.is_typeof and !block.is_comptime and sema.func != null) {14397 if (tv.val.tag() == .unreachable_value and !block.is_typeof and sema.func == null) {
14398 const msg = msg: {
14399 const name = name: {
14400 const file = sema.owner_decl.getFileScope();
14401 const tree = file.getTree(sema.mod.gpa) catch |err| {
14402 // In this case we emit a warning + a less precise source location.
14403 log.warn("unable to load {s}: {s}", .{
14404 file.sub_file_path, @errorName(err),
14405 });
14406 break :name null;
14407 };
14408 const node = sema.owner_decl.relativeToNodeIndex(inst_data.src_node);
14409 const token = tree.nodes.items(.main_token)[node];
14410 break :name tree.tokenSlice(token);
14411 };
14412
14413 const msg = if (name) |some|
14414 try sema.errMsg(block, inst_data.src(), "'{s}' not accessible outside function scope", .{some})
14415 else
14416 try sema.errMsg(block, inst_data.src(), "variable not accessible outside function scope", .{});
14417 errdefer msg.destroy(sema.gpa);
14418
14419 // TODO add "declared here" note
14420 break :msg msg;
14421 };
14422 return sema.failWithOwnedErrorMsg(msg);
14423 }
14424
14425 if (tv.val.tag() == .unreachable_value and !block.is_typeof and !block.is_comptime and sema.func != null) {
14398 const msg = msg: {14426 const msg = msg: {
14399 const name = name: {14427 const name = name: {
14400 const file = sema.owner_decl.getFileScope();14428 const file = sema.owner_decl.getFileScope();
test/cases/compile_errors/accessing_runtime_paramter_outside_function_scope.zig created+12
...@@ -0,0 +1,12 @@
1export fn entry(y: u8) void {
2 const Thing = struct {
3 y: u8 = y,
4 };
5 _ = @sizeOf(Thing);
6}
7
8// error
9// backend=stage2
10// target=native
11//
12// :3:17: error: 'y' not accessible outside function scope