zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 6547c3887eb604cf4d494d307927a50a12117708 (tree)
parent fa321a07cd985c672879c091db6dd0aa6b66f0b7
Author: Veikka Tuominen <git@vexu.eu>
Date:   Tue,  2 Aug 2022 19:03:38 +0300

Sema: add error for closure capture at runtime

Diffstat:
Msrc/Sema.zig | 30++++++++++++++++++++++++++++++
Atest/cases/compile_errors/accessing_runtime_parameter_from_outer_function.zig | 20++++++++++++++++++++
Dtest/cases/compile_errors/stage1/obj/accessing_runtime_parameter_from_outer_function.zig | 21---------------------
3 files changed, 50 insertions(+), 21 deletions(-)

diff --git 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/accessing_runtime_parameter_from_outer_function.zig b/test/cases/compile_errors/accessing_runtime_parameter_from_outer_function.zig @@ -0,0 +1,20 @@ +fn outer(y: u32) *const fn (u32) u32 { + const st = struct { + fn get(z: u32) u32 { + return z + y; + } + }; + return st.get; +} +export fn entry() void { + var func = outer(10); + var x = func(3); + _ = x; +} + +// error +// backend=stage2 +// target=native +// +// :4:24: error: 'y' not accessible from inner function +// :3:9: note: crossed function definition here diff --git a/test/cases/compile_errors/stage1/obj/accessing_runtime_parameter_from_outer_function.zig b/test/cases/compile_errors/stage1/obj/accessing_runtime_parameter_from_outer_function.zig @@ -1,21 +0,0 @@ -fn outer(y: u32) fn (u32) u32 { - const st = struct { - fn get(z: u32) u32 { - return z + y; - } - }; - return st.get; -} -export fn entry() void { - var func = outer(10); - var x = func(3); - _ = x; -} - -// error -// backend=stage1 -// 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