| ... | @@ -10483,10 +10483,19 @@ fn zirClosureCapture( | ... | @@ -10483,10 +10483,19 @@ fn zirClosureCapture( |
| 10483 | ) CompileError!void { | 10483 | ) CompileError!void { |
| 10484 | // TODO: Compile error when closed over values are modified | 10484 | // TODO: Compile error when closed over values are modified |
| 10485 | const inst_data = sema.code.instructions.items(.data)[inst].un_tok; | 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 | try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, .{ | 10496 | try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, .{ |
| 10488 | .ty = try tv.ty.copy(sema.perm_arena), | 10497 | .ty = try sema.typeOf(operand).copy(sema.perm_arena), |
| 10489 | .val = try tv.val.copy(sema.perm_arena), | 10498 | .val = try val.copy(sema.perm_arena), |
| 10490 | }); | 10499 | }); |
| 10491 | } | 10500 | } |
| 10492 | | 10501 | |