| author | |
| committer | |
| log | bcf2eb1a003d076c166d4ce9cba20f6ed9b53887 |
| tree | 0703024c1c2d2601cd0eee38ac729d01027c8857 |
| parent | b802a67562cc912213ebfc6ef8a380c775c999fe |
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 #112922 files changed, 27 insertions(+), 3 deletions(-)
src/Sema.zig+12-3| ... | ... | @@ -10483,10 +10483,19 @@ fn zirClosureCapture( |
| 10483 | 10483 | ) CompileError!void { |
| 10484 | 10484 | // TODO: Compile error when closed over values are modified |
| 10485 | 10485 | const inst_data = sema.code.instructions.items(.data)[inst].un_tok; |
| 10486 | const tv = try sema.resolveInstConst(block, inst_data.src(), inst_data.operand); | |
| 10486 | const src = inst_data.src(); | |
| 10487 | // Closures are not necessarily constant values. For example, the | |
| 10488 | // code might do something like this: | |
| 10489 | // fn foo(x: anytype) void { const S = struct {field: @TypeOf(x)}; } | |
| 10490 | // ...in which case the closure_capture instruction has access to a runtime | |
| 10491 | // value only. In such case we preserve the type and use a dummy runtime value. | |
| 10492 | const operand = sema.resolveInst(inst_data.operand); | |
| 10493 | const val = (try sema.resolveMaybeUndefValAllowVariables(block, src, operand)) orelse | |
| 10494 | Value.initTag(.generic_poison); | |
| 10495 | ||
| 10487 | 10496 | try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, .{ |
| 10488 | .ty = try tv.ty.copy(sema.perm_arena), | |
| 10489 | .val = try tv.val.copy(sema.perm_arena), | |
| 10497 | .ty = try sema.typeOf(operand).copy(sema.perm_arena), | |
| 10498 | .val = try val.copy(sema.perm_arena), | |
| 10490 | 10499 | }); |
| 10491 | 10500 | } |
| 10492 | 10501 |
test/behavior/eval.zig+15| ... | ... | @@ -878,3 +878,18 @@ test "const local with comptime init through array init" { |
| 878 | 878 | |
| 879 | 879 | try comptime expect(decls[0][0].name[0] == 'a'); |
| 880 | 880 | } |
| 881 | ||
| 882 | test "closure capture type of runtime-known parameter" { | |
| 883 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 884 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 885 | ||
| 886 | const S = struct { | |
| 887 | fn b(c: anytype) !void { | |
| 888 | const D = struct { c: @TypeOf(c) }; | |
| 889 | var d = D{ .c = c }; | |
| 890 | try expect(d.c == 1234); | |
| 891 | } | |
| 892 | }; | |
| 893 | var c: i32 = 1234; | |
| 894 | try S.b(c); | |
| 895 | } |