| ... | ... | @@ -3850,6 +3850,7 @@ fn structDeclInner( |
| 3850 | 3850 | astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items); |
| 3851 | 3851 | astgen.extra.appendSliceAssumeCapacity(fields_slice); |
| 3852 | 3852 | |
| 3853 | try gz.addNamespaceCaptures(&namespace); |
| 3853 | 3854 | return indexToRef(decl_inst); |
| 3854 | 3855 | } |
| 3855 | 3856 | |
| ... | ... | @@ -3993,6 +3994,7 @@ fn unionDeclInner( |
| 3993 | 3994 | astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items); |
| 3994 | 3995 | astgen.extra.appendSliceAssumeCapacity(fields_slice); |
| 3995 | 3996 | |
| 3997 | try gz.addNamespaceCaptures(&namespace); |
| 3996 | 3998 | return indexToRef(decl_inst); |
| 3997 | 3999 | } |
| 3998 | 4000 | |
| ... | ... | @@ -4234,6 +4236,7 @@ fn containerDecl( |
| 4234 | 4236 | astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items); |
| 4235 | 4237 | astgen.extra.appendSliceAssumeCapacity(fields_slice); |
| 4236 | 4238 | |
| 4239 | try gz.addNamespaceCaptures(&namespace); |
| 4237 | 4240 | return rvalue(gz, rl, indexToRef(decl_inst), node); |
| 4238 | 4241 | }, |
| 4239 | 4242 | .keyword_opaque => { |
| ... | ... | @@ -4268,6 +4271,7 @@ fn containerDecl( |
| 4268 | 4271 | try astgen.extra.ensureUnusedCapacity(gpa, decls_slice.len); |
| 4269 | 4272 | astgen.extra.appendSliceAssumeCapacity(decls_slice); |
| 4270 | 4273 | |
| 4274 | try gz.addNamespaceCaptures(&namespace); |
| 4271 | 4275 | return rvalue(gz, rl, indexToRef(decl_inst), node); |
| 4272 | 4276 | }, |
| 4273 | 4277 | else => unreachable, |
| ... | ... | @@ -6108,9 +6112,15 @@ fn tunnelThroughClosure( |
| 6108 | 6112 | // already has one for this value. |
| 6109 | 6113 | const gop = try ns.?.captures.getOrPut(gpa, refToIndex(value).?); |
| 6110 | 6114 | if (!gop.found_existing) { |
| 6111 | | // Make a new capture for this value |
| 6112 | | const capture_ref = try ns.?.declaring_gz.?.addUnTok(.closure_capture, value, token); |
| 6113 | | gop.value_ptr.* = refToIndex(capture_ref).?; |
| 6115 | // Make a new capture for this value but don't add it to the declaring_gz yet |
| 6116 | try gz.astgen.instructions.append(gz.astgen.gpa, .{ |
| 6117 | .tag = .closure_capture, |
| 6118 | .data = .{ .un_tok = .{ |
| 6119 | .operand = value, |
| 6120 | .src_tok = ns.?.declaring_gz.?.tokenIndexToRelative(token), |
| 6121 | } }, |
| 6122 | }); |
| 6123 | gop.value_ptr.* = @intCast(Zir.Inst.Index, gz.astgen.instructions.len - 1); |
| 6114 | 6124 | } |
| 6115 | 6125 | |
| 6116 | 6126 | // Add an instruction to get the value from the closure into |
| ... | ... | @@ -8736,7 +8746,7 @@ const Scope = struct { |
| 8736 | 8746 | |
| 8737 | 8747 | /// Map from the raw captured value to the instruction |
| 8738 | 8748 | /// ref of the capture for decls in this namespace |
| 8739 | | captures: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{}, |
| 8749 | captures: std.AutoArrayHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{}, |
| 8740 | 8750 | |
| 8741 | 8751 | pub fn deinit(self: *Namespace, gpa: *Allocator) void { |
| 8742 | 8752 | self.decls.deinit(gpa); |
| ... | ... | @@ -9876,6 +9886,15 @@ const GenZir = struct { |
| 9876 | 9886 | else => unreachable, |
| 9877 | 9887 | } |
| 9878 | 9888 | } |
| 9889 | |
| 9890 | fn addNamespaceCaptures(gz: *GenZir, namespace: *Scope.Namespace) !void { |
| 9891 | if (namespace.captures.count() > 0) { |
| 9892 | try gz.instructions.ensureUnusedCapacity(gz.astgen.gpa, namespace.captures.count()); |
| 9893 | for (namespace.captures.values()) |capture| { |
| 9894 | gz.instructions.appendAssumeCapacity(capture); |
| 9895 | } |
| 9896 | } |
| 9897 | } |
| 9879 | 9898 | }; |
| 9880 | 9899 | |
| 9881 | 9900 | /// This can only be for short-lived references; the memory becomes invalidated |