mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 01:04:43 +01:00
resolve some of my TODOs
This commit is contained in:
parent
b09b9340a6
commit
78db8c8de7
5 changed files with 142 additions and 184 deletions
129
src/Sema.zig
129
src/Sema.zig
|
|
@ -5746,91 +5746,94 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
|
|||
}
|
||||
}
|
||||
|
||||
const export_ty = ptr_ty.childType(zcu);
|
||||
if (!export_ty.validateExtern(.other, zcu)) {
|
||||
return sema.failWithOwnedErrorMsg(block, msg: {
|
||||
const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)});
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other);
|
||||
try sema.addDeclaredHereNote(msg, export_ty);
|
||||
break :msg msg;
|
||||
});
|
||||
}
|
||||
|
||||
const ptr_info = ip.indexToKey(ptr_val.toIntern()).ptr;
|
||||
switch (ptr_info.base_addr) {
|
||||
const target: Zcu.Exported = switch (ptr_info.base_addr) {
|
||||
.comptime_alloc, .int, .comptime_field => return sema.fail(block, ptr_src, "export target must be a global variable or a comptime-known constant", .{}),
|
||||
.eu_payload, .opt_payload, .field, .arr_elem => return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{}),
|
||||
.uav => |uav| {
|
||||
if (ptr_info.byte_offset != 0) {
|
||||
return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{});
|
||||
.uav => |uav| .{ .uav = uav.val },
|
||||
.nav => |orig_nav| target: {
|
||||
try sema.ensureNavResolved(block, src, orig_nav, .fully);
|
||||
const export_nav = switch (ip.indexToKey(ip.getNav(orig_nav).status.fully_resolved.val)) {
|
||||
.variable => |v| v.owner_nav,
|
||||
.@"extern" => |e| e.owner_nav,
|
||||
.func => |f| f.owner_nav,
|
||||
else => orig_nav,
|
||||
};
|
||||
if (ip.getNav(export_nav).getExtern(ip) != null) {
|
||||
return sema.fail(block, src, "export target cannot be extern", .{});
|
||||
}
|
||||
if (zcu.llvm_object != null and options.linkage == .internal) return;
|
||||
const export_ty = Value.fromInterned(uav.val).typeOf(zcu);
|
||||
if (!export_ty.validateExtern(.other, zcu)) {
|
||||
return sema.failWithOwnedErrorMsg(block, msg: {
|
||||
const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)});
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other);
|
||||
try sema.addDeclaredHereNote(msg, export_ty);
|
||||
break :msg msg;
|
||||
});
|
||||
}
|
||||
try sema.exports.append(zcu.gpa, .{
|
||||
.opts = options,
|
||||
.src = src,
|
||||
.exported = .{ .uav = uav.val },
|
||||
.status = .in_progress,
|
||||
});
|
||||
},
|
||||
.nav => |nav| {
|
||||
if (ptr_info.byte_offset != 0) {
|
||||
return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{});
|
||||
}
|
||||
try sema.analyzeExport(block, src, options, nav);
|
||||
try sema.maybeQueueFuncBodyAnalysis(block, src, export_nav);
|
||||
break :target .{ .nav = export_nav };
|
||||
},
|
||||
};
|
||||
if (ptr_info.byte_offset != 0) {
|
||||
return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{});
|
||||
}
|
||||
if (zcu.llvm_object != null and options.linkage == .internal) return;
|
||||
try sema.exports.append(zcu.gpa, .{
|
||||
.opts = options,
|
||||
.src = src,
|
||||
.exported = target,
|
||||
.status = .in_progress,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn analyzeExport(
|
||||
/// Asserts that `sema.owner` is a `.nav_val` whose value is resolved.
|
||||
///
|
||||
/// Exports that `Nav` by the given name with all other options set to default.
|
||||
pub fn analyzeExportSelfNav(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
src: LazySrcLoc,
|
||||
options: Zcu.Export.Options,
|
||||
orig_nav_index: InternPool.Nav.Index,
|
||||
name: InternPool.NullTerminatedString,
|
||||
) !void {
|
||||
const gpa = sema.gpa;
|
||||
const pt = sema.pt;
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
if (zcu.llvm_object != null and options.linkage == .internal)
|
||||
return;
|
||||
|
||||
try sema.ensureNavResolved(block, src, orig_nav_index, .fully);
|
||||
|
||||
const exported_nav_index = switch (ip.indexToKey(ip.getNav(orig_nav_index).status.fully_resolved.val)) {
|
||||
.variable => |v| v.owner_nav,
|
||||
.@"extern" => |e| e.owner_nav,
|
||||
.func => |f| f.owner_nav,
|
||||
else => orig_nav_index,
|
||||
};
|
||||
|
||||
const exported_nav = ip.getNav(exported_nav_index);
|
||||
const export_ty: Type = .fromInterned(exported_nav.typeOf(ip));
|
||||
const orig_nav = sema.owner.unwrap().nav_val;
|
||||
const export_val: Value = .fromInterned(ip.getNav(orig_nav).status.fully_resolved.val);
|
||||
const export_ty = export_val.typeOf(zcu);
|
||||
|
||||
if (!export_ty.validateExtern(.other, zcu)) {
|
||||
return sema.failWithOwnedErrorMsg(block, msg: {
|
||||
const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)});
|
||||
errdefer msg.destroy(gpa);
|
||||
|
||||
try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other);
|
||||
|
||||
try sema.addDeclaredHereNote(msg, export_ty);
|
||||
break :msg msg;
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: some backends might support re-exporting extern decls
|
||||
if (exported_nav.getExtern(ip) != null) {
|
||||
return sema.fail(block, src, "export target cannot be extern", .{});
|
||||
}
|
||||
|
||||
try sema.maybeQueueFuncBodyAnalysis(block, src, exported_nav_index);
|
||||
const export_nav = switch (ip.indexToKey(export_val.toIntern())) {
|
||||
.variable => |v| v.owner_nav,
|
||||
.@"extern" => |e| e.owner_nav,
|
||||
.func => |f| export_nav: {
|
||||
assert(export_ty.fnHasRuntimeBits(zcu)); // otherwise `validateExtern` failed above
|
||||
const orig_fn_index = ip.unwrapCoercedFunc(export_val.toIntern());
|
||||
try sema.addReferenceEntry(block, src, .wrap(.{ .func = orig_fn_index }));
|
||||
try zcu.ensureFuncBodyAnalysisQueued(orig_fn_index);
|
||||
break :export_nav f.owner_nav;
|
||||
},
|
||||
else => orig_nav,
|
||||
};
|
||||
|
||||
try sema.exports.append(gpa, .{
|
||||
.opts = options,
|
||||
.opts = .{ .name = name },
|
||||
.src = src,
|
||||
.exported = .{ .nav = exported_nav_index },
|
||||
.exported = .{ .nav = export_nav },
|
||||
.status = .in_progress,
|
||||
});
|
||||
}
|
||||
|
|
@ -33739,21 +33742,9 @@ pub fn flushExports(sema: *Sema) !void {
|
|||
const zcu = sema.pt.zcu;
|
||||
const gpa = zcu.gpa;
|
||||
|
||||
// There may be existing exports. For instance, a struct may export
|
||||
// things during both field type resolution and field default resolution.
|
||||
//
|
||||
// So, pick up and delete any existing exports. This strategy performs
|
||||
// redundant work, but that's okay, because this case is exceedingly rare.
|
||||
//
|
||||
// MLUGG TODO: is this still possible? if not, delete this logic and combine deleteUnitExports into resetUnit
|
||||
if (zcu.single_exports.get(sema.owner)) |export_idx| {
|
||||
try sema.exports.append(gpa, export_idx.ptr(zcu).*);
|
||||
} else if (zcu.multi_exports.get(sema.owner)) |info| {
|
||||
try sema.exports.appendSlice(gpa, zcu.all_exports.items[info.index..][0..info.len]);
|
||||
}
|
||||
zcu.deleteUnitExports(sema.owner);
|
||||
assert(!zcu.single_exports.contains(sema.owner));
|
||||
assert(!zcu.multi_exports.contains(sema.owner));
|
||||
|
||||
// `sema.exports` is completed; store the data into the `Zcu`.
|
||||
if (sema.exports.items.len == 1) {
|
||||
try zcu.single_exports.ensureUnusedCapacity(gpa, 1);
|
||||
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
|
|||
};
|
||||
}
|
||||
|
||||
fn setTypeName(
|
||||
pub fn setTypeName(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
wip: *const InternPool.WipContainerType,
|
||||
|
|
|
|||
|
|
@ -125,89 +125,77 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter
|
|||
return (try pt.aggregateValue(.fromInterned(ty), values)).toIntern();
|
||||
},
|
||||
.struct_literal => |init| {
|
||||
if (true) @panic("MLUGG TODO");
|
||||
const elems = try self.sema.arena.alloc(InternPool.Index, init.names.len);
|
||||
for (0..init.names.len) |i| {
|
||||
elems[i] = try self.lowerExprAnonResTy(init.vals.at(@intCast(i)));
|
||||
}
|
||||
const struct_ty = switch (try ip.getStructType(
|
||||
gpa,
|
||||
io,
|
||||
pt.tid,
|
||||
.{
|
||||
.layout = .auto,
|
||||
.fields_len = @intCast(init.names.len),
|
||||
.known_non_opv = false,
|
||||
.requires_comptime = .no,
|
||||
.any_comptime_fields = true,
|
||||
.any_default_inits = true,
|
||||
.inits_resolved = true,
|
||||
.any_aligned_fields = false,
|
||||
.key = .{ .reified = .{
|
||||
.zir_index = self.base_node_inst,
|
||||
.type_hash = hash: {
|
||||
var hasher: std.hash.Wyhash = .init(0);
|
||||
hasher.update(std.mem.asBytes(&node));
|
||||
hasher.update(std.mem.sliceAsBytes(elems));
|
||||
hasher.update(std.mem.sliceAsBytes(init.names));
|
||||
break :hash hasher.final();
|
||||
},
|
||||
} },
|
||||
const struct_ty: Type = switch (try ip.getReifiedStructType(gpa, io, pt.tid, .{
|
||||
.zir_index = self.base_node_inst,
|
||||
.type_hash = hash: {
|
||||
var hasher: std.hash.Wyhash = .init(0);
|
||||
hasher.update(std.mem.asBytes(&node));
|
||||
hasher.update(std.mem.sliceAsBytes(elems));
|
||||
hasher.update(std.mem.sliceAsBytes(init.names));
|
||||
break :hash hasher.final();
|
||||
},
|
||||
false,
|
||||
)) {
|
||||
.fields_len = @intCast(init.names.len),
|
||||
.layout = .auto,
|
||||
.any_comptime_fields = true,
|
||||
.any_field_defaults = true,
|
||||
.any_field_aligns = false,
|
||||
.packed_backing_int_type = .none,
|
||||
})) {
|
||||
.existing => |ty| .fromInterned(ty),
|
||||
.wip => |wip| ty: {
|
||||
errdefer wip.cancel(ip, pt.tid);
|
||||
const type_name = try self.sema.createTypeName(
|
||||
self.block,
|
||||
.anon,
|
||||
"struct",
|
||||
self.base_node_inst.resolve(ip),
|
||||
wip.index,
|
||||
);
|
||||
wip.setName(ip, type_name.name, type_name.nav);
|
||||
const block = self.block;
|
||||
const zcu = pt.zcu;
|
||||
try self.sema.setTypeName(block, &wip, .anon, "struct", self.base_node_inst.resolve(ip).?);
|
||||
|
||||
const struct_type = ip.loadStructType(wip.index);
|
||||
|
||||
for (init.names, 0..) |name, field_idx| {
|
||||
const name_interned = try ip.getOrPutString(
|
||||
// Reified structs have field information populated immediately.
|
||||
@memcpy(wip.field_values.get(ip), elems);
|
||||
if (init.names.len > 0) {
|
||||
// All fields are comptime, but unused bits remain zeroed.
|
||||
const unused_bits = switch (init.names.len % 32) {
|
||||
0 => 0,
|
||||
else => |n| 32 - n,
|
||||
};
|
||||
const comptime_bits = wip.field_is_comptime_bits.getAll(ip);
|
||||
@memset(comptime_bits[0 .. comptime_bits.len - 1], std.math.maxInt(u32));
|
||||
comptime_bits[comptime_bits.len - 1] = @as(u32, std.math.maxInt(u32)) >> @intCast(unused_bits);
|
||||
}
|
||||
for (
|
||||
init.names,
|
||||
wip.field_names.get(ip),
|
||||
wip.field_types.get(ip),
|
||||
wip.field_values.get(ip),
|
||||
) |zoir_name, *field_name, *field_ty, field_val| {
|
||||
field_name.* = try ip.getOrPutString(
|
||||
gpa,
|
||||
io,
|
||||
pt.tid,
|
||||
name.get(self.file.zoir.?),
|
||||
zoir_name.get(self.file.zoir.?),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
assert(struct_type.addFieldName(ip, name_interned) == null);
|
||||
struct_type.setFieldComptime(ip, field_idx);
|
||||
}
|
||||
|
||||
@memcpy(struct_type.field_inits.get(ip), elems);
|
||||
const types = struct_type.field_types.get(ip);
|
||||
for (0..init.names.len) |i| {
|
||||
types[i] = Value.fromInterned(elems[i]).typeOf(pt.zcu).toIntern();
|
||||
field_ty.* = ip.typeOf(field_val);
|
||||
}
|
||||
|
||||
const new_namespace_index = try pt.createNamespace(.{
|
||||
.parent = self.block.namespace.toOptional(),
|
||||
.parent = block.namespace.toOptional(),
|
||||
.owner_type = wip.index,
|
||||
.file_scope = self.block.getFileScopeIndex(pt.zcu),
|
||||
.generation = pt.zcu.generation,
|
||||
.file_scope = block.getFileScopeIndex(zcu),
|
||||
.generation = zcu.generation,
|
||||
});
|
||||
try pt.zcu.comp.queueJob(.{ .resolve_type_fully = wip.index });
|
||||
codegen_type: {
|
||||
if (pt.zcu.comp.config.use_llvm) break :codegen_type;
|
||||
if (self.block.ownerModule().strip) break :codegen_type;
|
||||
pt.zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
|
||||
try pt.zcu.comp.queueJob(.{ .link_type = wip.index });
|
||||
}
|
||||
break :ty wip.finish(ip, new_namespace_index);
|
||||
errdefer pt.destroyNamespace(new_namespace_index);
|
||||
if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
|
||||
break :ty .fromInterned(wip.finish(ip, new_namespace_index));
|
||||
},
|
||||
.existing => |ty| ty,
|
||||
};
|
||||
try self.sema.declareDependency(.{ .interned = struct_ty });
|
||||
try self.sema.addTypeReferenceEntry(self.nodeSrc(node), struct_ty);
|
||||
// No need for `ensureNamespaceUpToDate` because this type's namespace is always empty.
|
||||
try self.sema.ensureLayoutResolved(struct_ty, self.nodeSrc(node), .init);
|
||||
|
||||
return (try pt.aggregateValue(.fromInterned(struct_ty), elems)).toIntern();
|
||||
return (try pt.aggregateValue(struct_ty, elems)).toIntern();
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1954,7 +1954,6 @@ pub const PointerDeriveStep = union(enum) {
|
|||
/// which prefer field/elem accesses when lowering constant pointer values.
|
||||
/// It is also used by the Value printing logic for pointers.
|
||||
pub fn pointerDerivation(ptr_val: Value, arena: Allocator, pt: Zcu.PerThread, opt_sema: ?*Sema) Allocator.Error!PointerDeriveStep {
|
||||
// MLUGG TODO: audit tf outta this code
|
||||
const zcu = pt.zcu;
|
||||
const ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr;
|
||||
const base_derive: PointerDeriveStep = switch (ptr.base_addr) {
|
||||
|
|
|
|||
72
src/Zcu.zig
72
src/Zcu.zig
|
|
@ -3518,50 +3518,10 @@ pub const ImportResult = struct {
|
|||
module: ?*Package.Module,
|
||||
};
|
||||
|
||||
/// Delete all the Export objects that are caused by this `AnalUnit`. Re-analysis of
|
||||
/// this `AnalUnit` will cause them to be re-created (or not).
|
||||
pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void {
|
||||
const gpa = zcu.gpa;
|
||||
|
||||
const exports_base, const exports_len = if (zcu.single_exports.fetchSwapRemove(anal_unit)) |kv|
|
||||
.{ @intFromEnum(kv.value), 1 }
|
||||
else if (zcu.multi_exports.fetchSwapRemove(anal_unit)) |info|
|
||||
.{ info.value.index, info.value.len }
|
||||
else
|
||||
return;
|
||||
|
||||
const exports = zcu.all_exports.items[exports_base..][0..exports_len];
|
||||
|
||||
// In an only-c build, we're guaranteed to never use incremental compilation, so there are
|
||||
// guaranteed not to be any exports in the output file that need deleting (since we only call
|
||||
// `updateExports` on flush).
|
||||
// This case is needed because in some rare edge cases, `Sema` wants to add and delete exports
|
||||
// within a single update.
|
||||
if (dev.env.supports(.incremental)) {
|
||||
for (exports, exports_base..) |exp, export_index_usize| {
|
||||
const export_idx: Export.Index = @enumFromInt(export_index_usize);
|
||||
if (zcu.comp.bin_file) |lf| {
|
||||
lf.deleteExport(exp.exported, exp.opts.name);
|
||||
}
|
||||
if (zcu.failed_exports.fetchSwapRemove(export_idx)) |failed_kv| {
|
||||
failed_kv.value.destroy(gpa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zcu.free_exports.ensureUnusedCapacity(gpa, exports_len) catch {
|
||||
// This space will be reused eventually, so we need not propagate this error.
|
||||
// Just leak it for now, and let GC reclaim it later on.
|
||||
return;
|
||||
};
|
||||
for (exports_base..exports_base + exports_len) |export_idx| {
|
||||
zcu.free_exports.appendAssumeCapacity(@enumFromInt(export_idx));
|
||||
}
|
||||
}
|
||||
|
||||
/// Prepares `unit` for re-analysis by clearing all of the following state:
|
||||
/// * Compile errors associated with `unit`
|
||||
/// * Compile logs associated with `unit`
|
||||
/// * Exports performed by `unit`
|
||||
/// * Dependencies from `unit` on other things
|
||||
/// * References from `unit` to other units
|
||||
/// 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 {
|
|||
}
|
||||
}
|
||||
|
||||
// Exports
|
||||
exports: {
|
||||
const base: u32, const len: u32 = index: {
|
||||
if (zcu.single_exports.fetchSwapRemove(unit)) |kv| {
|
||||
break :index .{ @intFromEnum(kv.value), 1 };
|
||||
}
|
||||
if (zcu.multi_exports.fetchSwapRemove(unit)) |kv| {
|
||||
break :index .{ kv.value.index, kv.value.len };
|
||||
}
|
||||
break :exports;
|
||||
};
|
||||
for (zcu.all_exports.items[base..][0..len], base..) |exp, exp_index_usize| {
|
||||
const exp_index: Export.Index = @enumFromInt(exp_index_usize);
|
||||
if (zcu.comp.bin_file) |lf| {
|
||||
lf.deleteExport(exp.exported, exp.opts.name);
|
||||
}
|
||||
if (zcu.failed_exports.fetchSwapRemove(exp_index)) |failed_kv| {
|
||||
failed_kv.value.destroy(gpa);
|
||||
}
|
||||
}
|
||||
zcu.free_exports.ensureUnusedCapacity(gpa, len) catch {
|
||||
// This space will be reused eventually, so we need not propagate this error.
|
||||
// Just leak it for now, and let GC reclaim it later on.
|
||||
break :exports;
|
||||
};
|
||||
for (base..base + len) |exp_index| {
|
||||
zcu.free_exports.appendAssumeCapacity(@enumFromInt(exp_index));
|
||||
}
|
||||
}
|
||||
|
||||
// Dependencies
|
||||
zcu.intern_pool.removeDependenciesForDepender(gpa, unit);
|
||||
|
||||
|
|
|
|||
|
|
@ -752,7 +752,6 @@ pub fn ensureMemoizedStateUpToDate(
|
|||
if (was_outdated) {
|
||||
dev.check(.incremental);
|
||||
_ = zcu.outdated_ready.swapRemove(unit);
|
||||
// No need for `deleteUnitExports` because we never export anything.
|
||||
zcu.resetUnit(unit);
|
||||
} else {
|
||||
if (prev_failed) return error.AnalysisFail;
|
||||
|
|
@ -874,7 +873,6 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU
|
|||
_ = zcu.outdated_ready.swapRemove(anal_unit);
|
||||
// `was_outdated` can be true in the initial update for comptime units, so this isn't a `dev.check`.
|
||||
if (dev.env.supports(.incremental)) {
|
||||
zcu.deleteUnitExports(anal_unit);
|
||||
zcu.resetUnit(anal_unit);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1033,7 +1031,6 @@ pub fn ensureTypeLayoutUpToDate(
|
|||
_ = zcu.outdated_ready.swapRemove(anal_unit);
|
||||
// `was_outdated` is true in the initial update, so this isn't a `dev.check`.
|
||||
if (dev.env.supports(.incremental)) {
|
||||
zcu.deleteUnitExports(anal_unit);
|
||||
zcu.resetUnit(anal_unit);
|
||||
}
|
||||
// For types, we already know that we have to invalidate all dependees.
|
||||
|
|
@ -1151,7 +1148,6 @@ pub fn ensureNavValUpToDate(
|
|||
if (was_outdated) {
|
||||
dev.check(.incremental);
|
||||
_ = zcu.outdated_ready.swapRemove(anal_unit);
|
||||
zcu.deleteUnitExports(anal_unit);
|
||||
zcu.resetUnit(anal_unit);
|
||||
} else {
|
||||
// We can trust the current information about this unit.
|
||||
|
|
@ -1238,7 +1234,7 @@ fn analyzeNavVal(
|
|||
const zir_decl = zir.getDeclaration(inst_resolved.inst);
|
||||
|
||||
try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, reason);
|
||||
errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit);
|
||||
defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));
|
||||
|
||||
var analysis_arena: std.heap.ArenaAllocator = .init(gpa);
|
||||
defer analysis_arena.deinit();
|
||||
|
|
@ -1443,15 +1439,11 @@ fn analyzeNavVal(
|
|||
.@"addrspace" = modifiers.@"addrspace",
|
||||
});
|
||||
|
||||
// Mark the unit as completed before evaluating the export!
|
||||
// MLUGG TODO: do we really need to do this?
|
||||
assert(zcu.analysis_in_progress.swapRemove(anal_unit));
|
||||
|
||||
if (zir_decl.linkage == .@"export") {
|
||||
const export_src = block.src(.{ .token_offset = @enumFromInt(@intFromBool(zir_decl.is_pub)) });
|
||||
const name_slice = zir.nullTerminatedString(zir_decl.name);
|
||||
const name_ip = try ip.getOrPutString(gpa, io, pt.tid, name_slice, .no_embedded_nulls);
|
||||
try sema.analyzeExport(&block, export_src, .{ .name = name_ip }, nav_id);
|
||||
try sema.analyzeExportSelfNav(&block, export_src, name_ip);
|
||||
}
|
||||
|
||||
try sema.flushExports();
|
||||
|
|
@ -1514,7 +1506,6 @@ pub fn ensureNavTypeUpToDate(
|
|||
if (was_outdated) {
|
||||
dev.check(.incremental);
|
||||
_ = zcu.outdated_ready.swapRemove(anal_unit);
|
||||
zcu.deleteUnitExports(anal_unit);
|
||||
zcu.resetUnit(anal_unit);
|
||||
} else {
|
||||
// We can trust the current information about this unit.
|
||||
|
|
@ -1751,7 +1742,6 @@ pub fn ensureFuncBodyUpToDate(
|
|||
if (was_outdated) {
|
||||
dev.check(.incremental);
|
||||
_ = zcu.outdated_ready.swapRemove(anal_unit);
|
||||
zcu.deleteUnitExports(anal_unit);
|
||||
zcu.resetUnit(anal_unit);
|
||||
} else {
|
||||
// We can trust the current information about this function.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue