| author | |
| committer | |
| log | 03e23bcbdea2e832307085e5855ca20b51ac9d9a |
| tree | 761fe4f62155bf1873c389cb64af6337605e1076 |
| parent | c91b06ef52f31090b3c8fda9b9a419bf1391d805 |
| signature | Commit is signed but in an unrecognized format. |
5 files changed, 143 insertions(+), 185 deletions(-)
src/Sema.zig+60-69| ... | ... | @@ -5746,91 +5746,94 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 5746 | 5746 | } |
| 5747 | 5747 | } |
| 5748 | 5748 | |
| 5749 | const export_ty = ptr_ty.childType(zcu); | |
| 5750 | if (!export_ty.validateExtern(.other, zcu)) { | |
| 5751 | return sema.failWithOwnedErrorMsg(block, msg: { | |
| 5752 | const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)}); | |
| 5753 | errdefer msg.destroy(sema.gpa); | |
| 5754 | try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other); | |
| 5755 | try sema.addDeclaredHereNote(msg, export_ty); | |
| 5756 | break :msg msg; | |
| 5757 | }); | |
| 5758 | } | |
| 5759 | ||
| 5749 | 5760 | const ptr_info = ip.indexToKey(ptr_val.toIntern()).ptr; |
| 5750 | switch (ptr_info.base_addr) { | |
| 5761 | const target: Zcu.Exported = switch (ptr_info.base_addr) { | |
| 5751 | 5762 | .comptime_alloc, .int, .comptime_field => return sema.fail(block, ptr_src, "export target must be a global variable or a comptime-known constant", .{}), |
| 5752 | 5763 | .eu_payload, .opt_payload, .field, .arr_elem => return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{}), |
| 5753 | .uav => |uav| { | |
| 5754 | if (ptr_info.byte_offset != 0) { | |
| 5755 | return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{}); | |
| 5756 | } | |
| 5757 | if (zcu.llvm_object != null and options.linkage == .internal) return; | |
| 5758 | const export_ty = Value.fromInterned(uav.val).typeOf(zcu); | |
| 5759 | if (!export_ty.validateExtern(.other, zcu)) { | |
| 5760 | return sema.failWithOwnedErrorMsg(block, msg: { | |
| 5761 | const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)}); | |
| 5762 | errdefer msg.destroy(sema.gpa); | |
| 5763 | try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other); | |
| 5764 | try sema.addDeclaredHereNote(msg, export_ty); | |
| 5765 | break :msg msg; | |
| 5766 | }); | |
| 5767 | } | |
| 5768 | try sema.exports.append(zcu.gpa, .{ | |
| 5769 | .opts = options, | |
| 5770 | .src = src, | |
| 5771 | .exported = .{ .uav = uav.val }, | |
| 5772 | .status = .in_progress, | |
| 5773 | }); | |
| 5774 | }, | |
| 5775 | .nav => |nav| { | |
| 5776 | if (ptr_info.byte_offset != 0) { | |
| 5777 | return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{}); | |
| 5764 | .uav => |uav| .{ .uav = uav.val }, | |
| 5765 | .nav => |orig_nav| target: { | |
| 5766 | try sema.ensureNavResolved(block, src, orig_nav, .fully); | |
| 5767 | const export_nav = switch (ip.indexToKey(ip.getNav(orig_nav).status.fully_resolved.val)) { | |
| 5768 | .variable => |v| v.owner_nav, | |
| 5769 | .@"extern" => |e| e.owner_nav, | |
| 5770 | .func => |f| f.owner_nav, | |
| 5771 | else => orig_nav, | |
| 5772 | }; | |
| 5773 | if (ip.getNav(export_nav).getExtern(ip) != null) { | |
| 5774 | return sema.fail(block, src, "export target cannot be extern", .{}); | |
| 5778 | 5775 | } |
| 5779 | try sema.analyzeExport(block, src, options, nav); | |
| 5776 | try sema.maybeQueueFuncBodyAnalysis(block, src, export_nav); | |
| 5777 | break :target .{ .nav = export_nav }; | |
| 5780 | 5778 | }, |
| 5779 | }; | |
| 5780 | if (ptr_info.byte_offset != 0) { | |
| 5781 | return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{}); | |
| 5781 | 5782 | } |
| 5783 | if (zcu.llvm_object != null and options.linkage == .internal) return; | |
| 5784 | try sema.exports.append(zcu.gpa, .{ | |
| 5785 | .opts = options, | |
| 5786 | .src = src, | |
| 5787 | .exported = target, | |
| 5788 | .status = .in_progress, | |
| 5789 | }); | |
| 5782 | 5790 | } |
| 5783 | 5791 | |
| 5784 | pub fn analyzeExport( | |
| 5792 | /// Asserts that `sema.owner` is a `.nav_val` whose value is resolved. | |
| 5793 | /// | |
| 5794 | /// Exports that `Nav` by the given name with all other options set to default. | |
| 5795 | pub fn analyzeExportSelfNav( | |
| 5785 | 5796 | sema: *Sema, |
| 5786 | 5797 | block: *Block, |
| 5787 | 5798 | src: LazySrcLoc, |
| 5788 | options: Zcu.Export.Options, | |
| 5789 | orig_nav_index: InternPool.Nav.Index, | |
| 5799 | name: InternPool.NullTerminatedString, | |
| 5790 | 5800 | ) !void { |
| 5791 | 5801 | const gpa = sema.gpa; |
| 5792 | 5802 | const pt = sema.pt; |
| 5793 | 5803 | const zcu = pt.zcu; |
| 5794 | 5804 | const ip = &zcu.intern_pool; |
| 5795 | 5805 | |
| 5796 | if (zcu.llvm_object != null and options.linkage == .internal) | |
| 5797 | return; | |
| 5798 | ||
| 5799 | try sema.ensureNavResolved(block, src, orig_nav_index, .fully); | |
| 5800 | ||
| 5801 | const exported_nav_index = switch (ip.indexToKey(ip.getNav(orig_nav_index).status.fully_resolved.val)) { | |
| 5802 | .variable => |v| v.owner_nav, | |
| 5803 | .@"extern" => |e| e.owner_nav, | |
| 5804 | .func => |f| f.owner_nav, | |
| 5805 | else => orig_nav_index, | |
| 5806 | }; | |
| 5807 | ||
| 5808 | const exported_nav = ip.getNav(exported_nav_index); | |
| 5809 | const export_ty: Type = .fromInterned(exported_nav.typeOf(ip)); | |
| 5806 | const orig_nav = sema.owner.unwrap().nav_val; | |
| 5807 | const export_val: Value = .fromInterned(ip.getNav(orig_nav).status.fully_resolved.val); | |
| 5808 | const export_ty = export_val.typeOf(zcu); | |
| 5810 | 5809 | |
| 5811 | 5810 | if (!export_ty.validateExtern(.other, zcu)) { |
| 5812 | 5811 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 5813 | 5812 | const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)}); |
| 5814 | 5813 | errdefer msg.destroy(gpa); |
| 5815 | ||
| 5816 | 5814 | try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other); |
| 5817 | ||
| 5818 | 5815 | try sema.addDeclaredHereNote(msg, export_ty); |
| 5819 | 5816 | break :msg msg; |
| 5820 | 5817 | }); |
| 5821 | 5818 | } |
| 5822 | 5819 | |
| 5823 | // TODO: some backends might support re-exporting extern decls | |
| 5824 | if (exported_nav.getExtern(ip) != null) { | |
| 5825 | return sema.fail(block, src, "export target cannot be extern", .{}); | |
| 5826 | } | |
| 5827 | ||
| 5828 | try sema.maybeQueueFuncBodyAnalysis(block, src, exported_nav_index); | |
| 5820 | const export_nav = switch (ip.indexToKey(export_val.toIntern())) { | |
| 5821 | .variable => |v| v.owner_nav, | |
| 5822 | .@"extern" => |e| e.owner_nav, | |
| 5823 | .func => |f| export_nav: { | |
| 5824 | assert(export_ty.fnHasRuntimeBits(zcu)); // otherwise `validateExtern` failed above | |
| 5825 | const orig_fn_index = ip.unwrapCoercedFunc(export_val.toIntern()); | |
| 5826 | try sema.addReferenceEntry(block, src, .wrap(.{ .func = orig_fn_index })); | |
| 5827 | try zcu.ensureFuncBodyAnalysisQueued(orig_fn_index); | |
| 5828 | break :export_nav f.owner_nav; | |
| 5829 | }, | |
| 5830 | else => orig_nav, | |
| 5831 | }; | |
| 5829 | 5832 | |
| 5830 | 5833 | try sema.exports.append(gpa, .{ |
| 5831 | .opts = options, | |
| 5834 | .opts = .{ .name = name }, | |
| 5832 | 5835 | .src = src, |
| 5833 | .exported = .{ .nav = exported_nav_index }, | |
| 5836 | .exported = .{ .nav = export_nav }, | |
| 5834 | 5837 | .status = .in_progress, |
| 5835 | 5838 | }); |
| 5836 | 5839 | } |
| ... | ... | @@ -33739,21 +33742,9 @@ pub fn flushExports(sema: *Sema) !void { |
| 33739 | 33742 | const zcu = sema.pt.zcu; |
| 33740 | 33743 | const gpa = zcu.gpa; |
| 33741 | 33744 | |
| 33742 | // There may be existing exports. For instance, a struct may export | |
| 33743 | // things during both field type resolution and field default resolution. | |
| 33744 | // | |
| 33745 | // So, pick up and delete any existing exports. This strategy performs | |
| 33746 | // redundant work, but that's okay, because this case is exceedingly rare. | |
| 33747 | // | |
| 33748 | // MLUGG TODO: is this still possible? if not, delete this logic and combine deleteUnitExports into resetUnit | |
| 33749 | if (zcu.single_exports.get(sema.owner)) |export_idx| { | |
| 33750 | try sema.exports.append(gpa, export_idx.ptr(zcu).*); | |
| 33751 | } else if (zcu.multi_exports.get(sema.owner)) |info| { | |
| 33752 | try sema.exports.appendSlice(gpa, zcu.all_exports.items[info.index..][0..info.len]); | |
| 33753 | } | |
| 33754 | zcu.deleteUnitExports(sema.owner); | |
| 33745 | assert(!zcu.single_exports.contains(sema.owner)); | |
| 33746 | assert(!zcu.multi_exports.contains(sema.owner)); | |
| 33755 | 33747 | |
| 33756 | // `sema.exports` is completed; store the data into the `Zcu`. | |
| 33757 | 33748 | if (sema.exports.items.len == 1) { |
| 33758 | 33749 | try zcu.single_exports.ensureUnusedCapacity(gpa, 1); |
| 33759 | 33750 | const export_idx: Zcu.Export.Index = zcu.free_exports.pop() orelse idx: { |
| ... | ... | @@ -34038,7 +34029,7 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ |
| 34038 | 34029 | }; |
| 34039 | 34030 | } |
| 34040 | 34031 | |
| 34041 | fn setTypeName( | |
| 34032 | pub fn setTypeName( | |
| 34042 | 34033 | sema: *Sema, |
| 34043 | 34034 | block: *Block, |
| 34044 | 34035 | wip: *const InternPool.WipContainerType, |
src/Sema/LowerZon.zig+50-62| ... | ... | @@ -125,89 +125,77 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter |
| 125 | 125 | return (try pt.aggregateValue(.fromInterned(ty), values)).toIntern(); |
| 126 | 126 | }, |
| 127 | 127 | .struct_literal => |init| { |
| 128 | if (true) @panic("MLUGG TODO"); | |
| 129 | 128 | const elems = try self.sema.arena.alloc(InternPool.Index, init.names.len); |
| 130 | 129 | for (0..init.names.len) |i| { |
| 131 | 130 | elems[i] = try self.lowerExprAnonResTy(init.vals.at(@intCast(i))); |
| 132 | 131 | } |
| 133 | const struct_ty = switch (try ip.getStructType( | |
| 134 | gpa, | |
| 135 | io, | |
| 136 | pt.tid, | |
| 137 | .{ | |
| 138 | .layout = .auto, | |
| 139 | .fields_len = @intCast(init.names.len), | |
| 140 | .known_non_opv = false, | |
| 141 | .requires_comptime = .no, | |
| 142 | .any_comptime_fields = true, | |
| 143 | .any_default_inits = true, | |
| 144 | .inits_resolved = true, | |
| 145 | .any_aligned_fields = false, | |
| 146 | .key = .{ .reified = .{ | |
| 147 | .zir_index = self.base_node_inst, | |
| 148 | .type_hash = hash: { | |
| 149 | var hasher: std.hash.Wyhash = .init(0); | |
| 150 | hasher.update(std.mem.asBytes(&node)); | |
| 151 | hasher.update(std.mem.sliceAsBytes(elems)); | |
| 152 | hasher.update(std.mem.sliceAsBytes(init.names)); | |
| 153 | break :hash hasher.final(); | |
| 154 | }, | |
| 155 | } }, | |
| 132 | const struct_ty: Type = switch (try ip.getReifiedStructType(gpa, io, pt.tid, .{ | |
| 133 | .zir_index = self.base_node_inst, | |
| 134 | .type_hash = hash: { | |
| 135 | var hasher: std.hash.Wyhash = .init(0); | |
| 136 | hasher.update(std.mem.asBytes(&node)); | |
| 137 | hasher.update(std.mem.sliceAsBytes(elems)); | |
| 138 | hasher.update(std.mem.sliceAsBytes(init.names)); | |
| 139 | break :hash hasher.final(); | |
| 156 | 140 | }, |
| 157 | false, | |
| 158 | )) { | |
| 141 | .fields_len = @intCast(init.names.len), | |
| 142 | .layout = .auto, | |
| 143 | .any_comptime_fields = true, | |
| 144 | .any_field_defaults = true, | |
| 145 | .any_field_aligns = false, | |
| 146 | .packed_backing_int_type = .none, | |
| 147 | })) { | |
| 148 | .existing => |ty| .fromInterned(ty), | |
| 159 | 149 | .wip => |wip| ty: { |
| 160 | 150 | errdefer wip.cancel(ip, pt.tid); |
| 161 | const type_name = try self.sema.createTypeName( | |
| 162 | self.block, | |
| 163 | .anon, | |
| 164 | "struct", | |
| 165 | self.base_node_inst.resolve(ip), | |
| 166 | wip.index, | |
| 167 | ); | |
| 168 | wip.setName(ip, type_name.name, type_name.nav); | |
| 169 | ||
| 170 | const struct_type = ip.loadStructType(wip.index); | |
| 171 | ||
| 172 | for (init.names, 0..) |name, field_idx| { | |
| 173 | const name_interned = try ip.getOrPutString( | |
| 151 | const block = self.block; | |
| 152 | const zcu = pt.zcu; | |
| 153 | try self.sema.setTypeName(block, &wip, .anon, "struct", self.base_node_inst.resolve(ip).?); | |
| 154 | ||
| 155 | // Reified structs have field information populated immediately. | |
| 156 | @memcpy(wip.field_values.get(ip), elems); | |
| 157 | if (init.names.len > 0) { | |
| 158 | // All fields are comptime, but unused bits remain zeroed. | |
| 159 | const unused_bits = switch (init.names.len % 32) { | |
| 160 | 0 => 0, | |
| 161 | else => |n| 32 - n, | |
| 162 | }; | |
| 163 | const comptime_bits = wip.field_is_comptime_bits.getAll(ip); | |
| 164 | @memset(comptime_bits[0 .. comptime_bits.len - 1], std.math.maxInt(u32)); | |
| 165 | comptime_bits[comptime_bits.len - 1] = @as(u32, std.math.maxInt(u32)) >> @intCast(unused_bits); | |
| 166 | } | |
| 167 | for ( | |
| 168 | init.names, | |
| 169 | wip.field_names.get(ip), | |
| 170 | wip.field_types.get(ip), | |
| 171 | wip.field_values.get(ip), | |
| 172 | ) |zoir_name, *field_name, *field_ty, field_val| { | |
| 173 | field_name.* = try ip.getOrPutString( | |
| 174 | 174 | gpa, |
| 175 | 175 | io, |
| 176 | 176 | pt.tid, |
| 177 | name.get(self.file.zoir.?), | |
| 177 | zoir_name.get(self.file.zoir.?), | |
| 178 | 178 | .no_embedded_nulls, |
| 179 | 179 | ); |
| 180 | assert(struct_type.addFieldName(ip, name_interned) == null); | |
| 181 | struct_type.setFieldComptime(ip, field_idx); | |
| 182 | } | |
| 183 | ||
| 184 | @memcpy(struct_type.field_inits.get(ip), elems); | |
| 185 | const types = struct_type.field_types.get(ip); | |
| 186 | for (0..init.names.len) |i| { | |
| 187 | types[i] = Value.fromInterned(elems[i]).typeOf(pt.zcu).toIntern(); | |
| 180 | field_ty.* = ip.typeOf(field_val); | |
| 188 | 181 | } |
| 189 | 182 | |
| 190 | 183 | const new_namespace_index = try pt.createNamespace(.{ |
| 191 | .parent = self.block.namespace.toOptional(), | |
| 184 | .parent = block.namespace.toOptional(), | |
| 192 | 185 | .owner_type = wip.index, |
| 193 | .file_scope = self.block.getFileScopeIndex(pt.zcu), | |
| 194 | .generation = pt.zcu.generation, | |
| 186 | .file_scope = block.getFileScopeIndex(zcu), | |
| 187 | .generation = zcu.generation, | |
| 195 | 188 | }); |
| 196 | try pt.zcu.comp.queueJob(.{ .resolve_type_fully = wip.index }); | |
| 197 | codegen_type: { | |
| 198 | if (pt.zcu.comp.config.use_llvm) break :codegen_type; | |
| 199 | if (self.block.ownerModule().strip) break :codegen_type; | |
| 200 | pt.zcu.comp.link_prog_node.increaseEstimatedTotalItems(1); | |
| 201 | try pt.zcu.comp.queueJob(.{ .link_type = wip.index }); | |
| 202 | } | |
| 203 | break :ty wip.finish(ip, new_namespace_index); | |
| 189 | errdefer pt.destroyNamespace(new_namespace_index); | |
| 190 | if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index); | |
| 191 | break :ty .fromInterned(wip.finish(ip, new_namespace_index)); | |
| 204 | 192 | }, |
| 205 | .existing => |ty| ty, | |
| 206 | 193 | }; |
| 207 | try self.sema.declareDependency(.{ .interned = struct_ty }); | |
| 208 | 194 | try self.sema.addTypeReferenceEntry(self.nodeSrc(node), struct_ty); |
| 195 | // No need for `ensureNamespaceUpToDate` because this type's namespace is always empty. | |
| 196 | try self.sema.ensureLayoutResolved(struct_ty, self.nodeSrc(node), .init); | |
| 209 | 197 | |
| 210 | return (try pt.aggregateValue(.fromInterned(struct_ty), elems)).toIntern(); | |
| 198 | return (try pt.aggregateValue(struct_ty, elems)).toIntern(); | |
| 211 | 199 | }, |
| 212 | 200 | } |
| 213 | 201 | } |
src/Value.zig-1| ... | ... | @@ -1954,7 +1954,6 @@ pub const PointerDeriveStep = union(enum) { |
| 1954 | 1954 | /// which prefer field/elem accesses when lowering constant pointer values. |
| 1955 | 1955 | /// It is also used by the Value printing logic for pointers. |
| 1956 | 1956 | pub fn pointerDerivation(ptr_val: Value, arena: Allocator, pt: Zcu.PerThread, opt_sema: ?*Sema) Allocator.Error!PointerDeriveStep { |
| 1957 | // MLUGG TODO: audit tf outta this code | |
| 1958 | 1957 | const zcu = pt.zcu; |
| 1959 | 1958 | const ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr; |
| 1960 | 1959 | const base_derive: PointerDeriveStep = switch (ptr.base_addr) { |
src/Zcu.zig+31-41| ... | ... | @@ -3518,50 +3518,10 @@ pub const ImportResult = struct { |
| 3518 | 3518 | module: ?*Package.Module, |
| 3519 | 3519 | }; |
| 3520 | 3520 | |
| 3521 | /// Delete all the Export objects that are caused by this `AnalUnit`. Re-analysis of | |
| 3522 | /// this `AnalUnit` will cause them to be re-created (or not). | |
| 3523 | pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void { | |
| 3524 | const gpa = zcu.gpa; | |
| 3525 | ||
| 3526 | const exports_base, const exports_len = if (zcu.single_exports.fetchSwapRemove(anal_unit)) |kv| | |
| 3527 | .{ @intFromEnum(kv.value), 1 } | |
| 3528 | else if (zcu.multi_exports.fetchSwapRemove(anal_unit)) |info| | |
| 3529 | .{ info.value.index, info.value.len } | |
| 3530 | else | |
| 3531 | return; | |
| 3532 | ||
| 3533 | const exports = zcu.all_exports.items[exports_base..][0..exports_len]; | |
| 3534 | ||
| 3535 | // In an only-c build, we're guaranteed to never use incremental compilation, so there are | |
| 3536 | // guaranteed not to be any exports in the output file that need deleting (since we only call | |
| 3537 | // `updateExports` on flush). | |
| 3538 | // This case is needed because in some rare edge cases, `Sema` wants to add and delete exports | |
| 3539 | // within a single update. | |
| 3540 | if (dev.env.supports(.incremental)) { | |
| 3541 | for (exports, exports_base..) |exp, export_index_usize| { | |
| 3542 | const export_idx: Export.Index = @enumFromInt(export_index_usize); | |
| 3543 | if (zcu.comp.bin_file) |lf| { | |
| 3544 | lf.deleteExport(exp.exported, exp.opts.name); | |
| 3545 | } | |
| 3546 | if (zcu.failed_exports.fetchSwapRemove(export_idx)) |failed_kv| { | |
| 3547 | failed_kv.value.destroy(gpa); | |
| 3548 | } | |
| 3549 | } | |
| 3550 | } | |
| 3551 | ||
| 3552 | zcu.free_exports.ensureUnusedCapacity(gpa, exports_len) catch { | |
| 3553 | // This space will be reused eventually, so we need not propagate this error. | |
| 3554 | // Just leak it for now, and let GC reclaim it later on. | |
| 3555 | return; | |
| 3556 | }; | |
| 3557 | for (exports_base..exports_base + exports_len) |export_idx| { | |
| 3558 | zcu.free_exports.appendAssumeCapacity(@enumFromInt(export_idx)); | |
| 3559 | } | |
| 3560 | } | |
| 3561 | ||
| 3562 | 3521 | /// Prepares `unit` for re-analysis by clearing all of the following state: |
| 3563 | 3522 | /// * Compile errors associated with `unit` |
| 3564 | 3523 | /// * Compile logs associated with `unit` |
| 3524 | /// * Exports performed by `unit` | |
| 3565 | 3525 | /// * Dependencies from `unit` on other things |
| 3566 | 3526 | /// * References from `unit` to other units |
| 3567 | 3527 | /// Delete all references in `reference_table` which are caused by `unit`, and all dependencies it |
| ... | ... | @@ -3593,6 +3553,36 @@ pub fn resetUnit(zcu: *Zcu, unit: AnalUnit) void { |
| 3593 | 3553 | } |
| 3594 | 3554 | } |
| 3595 | 3555 | |
| 3556 | // Exports | |
| 3557 | exports: { | |
| 3558 | const base: u32, const len: u32 = index: { | |
| 3559 | if (zcu.single_exports.fetchSwapRemove(unit)) |kv| { | |
| 3560 | break :index .{ @intFromEnum(kv.value), 1 }; | |
| 3561 | } | |
| 3562 | if (zcu.multi_exports.fetchSwapRemove(unit)) |kv| { | |
| 3563 | break :index .{ kv.value.index, kv.value.len }; | |
| 3564 | } | |
| 3565 | break :exports; | |
| 3566 | }; | |
| 3567 | for (zcu.all_exports.items[base..][0..len], base..) |exp, exp_index_usize| { | |
| 3568 | const exp_index: Export.Index = @enumFromInt(exp_index_usize); | |
| 3569 | if (zcu.comp.bin_file) |lf| { | |
| 3570 | lf.deleteExport(exp.exported, exp.opts.name); | |
| 3571 | } | |
| 3572 | if (zcu.failed_exports.fetchSwapRemove(exp_index)) |failed_kv| { | |
| 3573 | failed_kv.value.destroy(gpa); | |
| 3574 | } | |
| 3575 | } | |
| 3576 | zcu.free_exports.ensureUnusedCapacity(gpa, len) catch { | |
| 3577 | // This space will be reused eventually, so we need not propagate this error. | |
| 3578 | // Just leak it for now, and let GC reclaim it later on. | |
| 3579 | break :exports; | |
| 3580 | }; | |
| 3581 | for (base..base + len) |exp_index| { | |
| 3582 | zcu.free_exports.appendAssumeCapacity(@enumFromInt(exp_index)); | |
| 3583 | } | |
| 3584 | } | |
| 3585 | ||
| 3596 | 3586 | // Dependencies |
| 3597 | 3587 | zcu.intern_pool.removeDependenciesForDepender(gpa, unit); |
| 3598 | 3588 |
src/Zcu/PerThread.zig+2-12| ... | ... | @@ -752,7 +752,6 @@ pub fn ensureMemoizedStateUpToDate( |
| 752 | 752 | if (was_outdated) { |
| 753 | 753 | dev.check(.incremental); |
| 754 | 754 | _ = zcu.outdated_ready.swapRemove(unit); |
| 755 | // No need for `deleteUnitExports` because we never export anything. | |
| 756 | 755 | zcu.resetUnit(unit); |
| 757 | 756 | } else { |
| 758 | 757 | if (prev_failed) return error.AnalysisFail; |
| ... | ... | @@ -874,7 +873,6 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU |
| 874 | 873 | _ = zcu.outdated_ready.swapRemove(anal_unit); |
| 875 | 874 | // `was_outdated` can be true in the initial update for comptime units, so this isn't a `dev.check`. |
| 876 | 875 | if (dev.env.supports(.incremental)) { |
| 877 | zcu.deleteUnitExports(anal_unit); | |
| 878 | 876 | zcu.resetUnit(anal_unit); |
| 879 | 877 | } |
| 880 | 878 | } else { |
| ... | ... | @@ -1033,7 +1031,6 @@ pub fn ensureTypeLayoutUpToDate( |
| 1033 | 1031 | _ = zcu.outdated_ready.swapRemove(anal_unit); |
| 1034 | 1032 | // `was_outdated` is true in the initial update, so this isn't a `dev.check`. |
| 1035 | 1033 | if (dev.env.supports(.incremental)) { |
| 1036 | zcu.deleteUnitExports(anal_unit); | |
| 1037 | 1034 | zcu.resetUnit(anal_unit); |
| 1038 | 1035 | } |
| 1039 | 1036 | // For types, we already know that we have to invalidate all dependees. |
| ... | ... | @@ -1151,7 +1148,6 @@ pub fn ensureNavValUpToDate( |
| 1151 | 1148 | if (was_outdated) { |
| 1152 | 1149 | dev.check(.incremental); |
| 1153 | 1150 | _ = zcu.outdated_ready.swapRemove(anal_unit); |
| 1154 | zcu.deleteUnitExports(anal_unit); | |
| 1155 | 1151 | zcu.resetUnit(anal_unit); |
| 1156 | 1152 | } else { |
| 1157 | 1153 | // We can trust the current information about this unit. |
| ... | ... | @@ -1238,7 +1234,7 @@ fn analyzeNavVal( |
| 1238 | 1234 | const zir_decl = zir.getDeclaration(inst_resolved.inst); |
| 1239 | 1235 | |
| 1240 | 1236 | try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, reason); |
| 1241 | errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit); | |
| 1237 | defer assert(zcu.analysis_in_progress.swapRemove(anal_unit)); | |
| 1242 | 1238 | |
| 1243 | 1239 | var analysis_arena: std.heap.ArenaAllocator = .init(gpa); |
| 1244 | 1240 | defer analysis_arena.deinit(); |
| ... | ... | @@ -1443,15 +1439,11 @@ fn analyzeNavVal( |
| 1443 | 1439 | .@"addrspace" = modifiers.@"addrspace", |
| 1444 | 1440 | }); |
| 1445 | 1441 | |
| 1446 | // Mark the unit as completed before evaluating the export! | |
| 1447 | // MLUGG TODO: do we really need to do this? | |
| 1448 | assert(zcu.analysis_in_progress.swapRemove(anal_unit)); | |
| 1449 | ||
| 1450 | 1442 | if (zir_decl.linkage == .@"export") { |
| 1451 | 1443 | const export_src = block.src(.{ .token_offset = @enumFromInt(@intFromBool(zir_decl.is_pub)) }); |
| 1452 | 1444 | const name_slice = zir.nullTerminatedString(zir_decl.name); |
| 1453 | 1445 | const name_ip = try ip.getOrPutString(gpa, io, pt.tid, name_slice, .no_embedded_nulls); |
| 1454 | try sema.analyzeExport(&block, export_src, .{ .name = name_ip }, nav_id); | |
| 1446 | try sema.analyzeExportSelfNav(&block, export_src, name_ip); | |
| 1455 | 1447 | } |
| 1456 | 1448 | |
| 1457 | 1449 | try sema.flushExports(); |
| ... | ... | @@ -1514,7 +1506,6 @@ pub fn ensureNavTypeUpToDate( |
| 1514 | 1506 | if (was_outdated) { |
| 1515 | 1507 | dev.check(.incremental); |
| 1516 | 1508 | _ = zcu.outdated_ready.swapRemove(anal_unit); |
| 1517 | zcu.deleteUnitExports(anal_unit); | |
| 1518 | 1509 | zcu.resetUnit(anal_unit); |
| 1519 | 1510 | } else { |
| 1520 | 1511 | // We can trust the current information about this unit. |
| ... | ... | @@ -1751,7 +1742,6 @@ pub fn ensureFuncBodyUpToDate( |
| 1751 | 1742 | if (was_outdated) { |
| 1752 | 1743 | dev.check(.incremental); |
| 1753 | 1744 | _ = zcu.outdated_ready.swapRemove(anal_unit); |
| 1754 | zcu.deleteUnitExports(anal_unit); | |
| 1755 | 1745 | zcu.resetUnit(anal_unit); |
| 1756 | 1746 | } else { |
| 1757 | 1747 | // We can trust the current information about this function. |