mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 12:59:04 +00:00
Sema: fix closure capture typeof runtime-known parameter
Closures are not necessarily constant values. For example, Zig
code might do something like this:
fn foo(x: anytype) void {
const S = struct {field: @TypeOf(x)};
}
...in which case the closure_capture instruction has access to a
runtime value only. In such case we preserve the type and use a
dummy runtime value.
closes #11292
This commit is contained in:
parent
b802a67562
commit
bcf2eb1a00
15
src/Sema.zig
15
src/Sema.zig
@ -10483,10 +10483,19 @@ fn zirClosureCapture(
|
||||
) CompileError!void {
|
||||
// TODO: Compile error when closed over values are modified
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
|
||||
const tv = try sema.resolveInstConst(block, inst_data.src(), inst_data.operand);
|
||||
const src = inst_data.src();
|
||||
// Closures are not necessarily constant values. For example, the
|
||||
// code might do something like this:
|
||||
// fn foo(x: anytype) void { const S = struct {field: @TypeOf(x)}; }
|
||||
// ...in which case the closure_capture instruction has access to a runtime
|
||||
// value only. In such case we preserve the type and use a dummy runtime value.
|
||||
const operand = sema.resolveInst(inst_data.operand);
|
||||
const val = (try sema.resolveMaybeUndefValAllowVariables(block, src, operand)) orelse
|
||||
Value.initTag(.generic_poison);
|
||||
|
||||
try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, .{
|
||||
.ty = try tv.ty.copy(sema.perm_arena),
|
||||
.val = try tv.val.copy(sema.perm_arena),
|
||||
.ty = try sema.typeOf(operand).copy(sema.perm_arena),
|
||||
.val = try val.copy(sema.perm_arena),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -878,3 +878,18 @@ test "const local with comptime init through array init" {
|
||||
|
||||
try comptime expect(decls[0][0].name[0] == 'a');
|
||||
}
|
||||
|
||||
test "closure capture type of runtime-known parameter" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn b(c: anytype) !void {
|
||||
const D = struct { c: @TypeOf(c) };
|
||||
var d = D{ .c = c };
|
||||
try expect(d.c == 1234);
|
||||
}
|
||||
};
|
||||
var c: i32 = 1234;
|
||||
try S.b(c);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user