mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
compiler: progress towards incremental
Most basic re-analysis logic is now in place. Trivial updates are hitting linker assertions.
This commit is contained in:
parent
7ba8641d19
commit
1421d329a3
@ -7103,7 +7103,7 @@ pub fn getGeneratedTagEnumType(ip: *InternPool, gpa: Allocator, ini: GeneratedTa
|
||||
return @enumFromInt(gop.index);
|
||||
}
|
||||
|
||||
pub const OpaqueTypeIni = struct {
|
||||
pub const OpaqueTypeInit = struct {
|
||||
has_namespace: bool,
|
||||
key: union(enum) {
|
||||
declared: struct {
|
||||
@ -7117,7 +7117,7 @@ pub const OpaqueTypeIni = struct {
|
||||
},
|
||||
};
|
||||
|
||||
pub fn getOpaqueType(ip: *InternPool, gpa: Allocator, ini: OpaqueTypeIni) Allocator.Error!WipNamespaceType.Result {
|
||||
pub fn getOpaqueType(ip: *InternPool, gpa: Allocator, ini: OpaqueTypeInit) Allocator.Error!WipNamespaceType.Result {
|
||||
const adapter: KeyAdapter = .{ .intern_pool = ip };
|
||||
const gop = try ip.map.getOrPutAdapted(gpa, Key{ .opaque_type = switch (ini.key) {
|
||||
.declared => |d| .{ .declared = .{
|
||||
|
||||
122
src/Module.zig
122
src/Module.zig
@ -762,14 +762,14 @@ pub const Namespace = struct {
|
||||
zcu: *Zcu,
|
||||
|
||||
pub fn hash(ctx: @This(), decl_index: Decl.Index) u32 {
|
||||
const decl = ctx.module.declPtr(decl_index);
|
||||
const decl = ctx.zcu.declPtr(decl_index);
|
||||
return std.hash.uint32(@intFromEnum(decl.name));
|
||||
}
|
||||
|
||||
pub fn eql(ctx: @This(), a_decl_index: Decl.Index, b_decl_index: Decl.Index, b_index: usize) bool {
|
||||
_ = b_index;
|
||||
const a_decl = ctx.module.declPtr(a_decl_index);
|
||||
const b_decl = ctx.module.declPtr(b_decl_index);
|
||||
const a_decl = ctx.zcu.declPtr(a_decl_index);
|
||||
const b_decl = ctx.zcu.declPtr(b_decl_index);
|
||||
return a_decl.name == b_decl.name;
|
||||
}
|
||||
};
|
||||
@ -2655,7 +2655,7 @@ pub fn markDependeeOutdated(zcu: *Zcu, dependee: InternPool.Dependee) !void {
|
||||
if (opt_po_entry) |e| e.value else 0,
|
||||
);
|
||||
log.debug("outdated: {}", .{depender});
|
||||
if (opt_po_entry != null) {
|
||||
if (opt_po_entry == null) {
|
||||
// This is a new entry with no PO dependencies.
|
||||
try zcu.outdated_ready.put(zcu.gpa, depender, {});
|
||||
}
|
||||
@ -2989,10 +2989,10 @@ pub fn mapOldZirToNew(
|
||||
|
||||
/// Like `ensureDeclAnalyzed`, but the Decl is a file's root Decl.
|
||||
pub fn ensureFileAnalyzed(zcu: *Zcu, file: *File) SemaError!void {
|
||||
if (file.root_decl == .none) {
|
||||
return zcu.semaFile(file);
|
||||
if (file.root_decl.unwrap()) |existing_root| {
|
||||
return zcu.ensureDeclAnalyzed(existing_root);
|
||||
} else {
|
||||
return zcu.ensureDeclAnalyzed(file.root_decl);
|
||||
return zcu.semaFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3006,6 +3006,11 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
|
||||
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
log.debug("ensureDeclAnalyzed '{d}' (name '{}')", .{
|
||||
@intFromEnum(decl_index),
|
||||
decl.name.fmt(&mod.intern_pool),
|
||||
});
|
||||
|
||||
// Determine whether or not this Decl is outdated, i.e. requires re-analysis
|
||||
// even if `complete`. If a Decl is PO, we pessismistically assume that it
|
||||
// *does* require re-analysis, to ensure that the Decl is definitely
|
||||
@ -3099,11 +3104,13 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
|
||||
// TODO: we do not yet have separate dependencies for decl values vs types.
|
||||
if (decl_was_outdated) {
|
||||
if (sema_result.invalidate_decl_val or sema_result.invalidate_decl_ref) {
|
||||
log.debug("Decl tv invalidated ('{d}')", .{@intFromEnum(decl_index)});
|
||||
// This dependency was marked as PO, meaning dependees were waiting
|
||||
// on its analysis result, and it has turned out to be outdated.
|
||||
// Update dependees accordingly.
|
||||
try mod.markDependeeOutdated(.{ .decl_val = decl_index });
|
||||
} else {
|
||||
log.debug("Decl tv up-to-date ('{d}')", .{@intFromEnum(decl_index)});
|
||||
// This dependency was previously PO, but turned out to be up-to-date.
|
||||
// We do not need to queue successive analysis.
|
||||
try mod.markPoDependeeUpToDate(.{ .decl_val = decl_index });
|
||||
@ -3115,11 +3122,31 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const gpa = zcu.gpa;
|
||||
const ip = &zcu.intern_pool;
|
||||
const func = zcu.funcInfo(func_index);
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
|
||||
log.debug("ensureFuncBodyAnalyzed '{d}' (instance of '{}')", .{
|
||||
@intFromEnum(func_index),
|
||||
decl.name.fmt(ip),
|
||||
});
|
||||
|
||||
// First, our owner decl must be up-to-date. This will always be the case
|
||||
// during the first update, but may not on successive updates if we happen
|
||||
// to get analyzed before our parent decl.
|
||||
try zcu.ensureDeclAnalyzed(decl_index);
|
||||
|
||||
// On an update, it's possible this function changed such that our owner
|
||||
// decl now refers to a different function, making this one orphaned. If
|
||||
// that's the case, we should remove this function from the binary.
|
||||
if (decl.val.ip_index != func_index) {
|
||||
ip.removeDependenciesForDepender(gpa, InternPool.Depender.wrap(.{ .func = func_index }));
|
||||
ip.remove(func_index);
|
||||
@panic("TODO: remove orphaned function from binary");
|
||||
}
|
||||
|
||||
switch (decl.analysis) {
|
||||
.unreferenced => unreachable,
|
||||
.in_progress => unreachable,
|
||||
@ -3143,7 +3170,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError
|
||||
}
|
||||
|
||||
switch (func.analysis(ip).state) {
|
||||
.success,
|
||||
.success => if (!was_outdated) return,
|
||||
.sema_failure,
|
||||
.dependency_failure,
|
||||
.codegen_failure,
|
||||
@ -3153,7 +3180,10 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError
|
||||
.inline_only => unreachable, // don't queue work for this
|
||||
}
|
||||
|
||||
const gpa = zcu.gpa;
|
||||
log.debug("analyze and generate fn body '{d}'; reason='{s}'", .{
|
||||
@intFromEnum(func_index),
|
||||
if (was_outdated) "outdated" else "never analyzed",
|
||||
});
|
||||
|
||||
var tmp_arena = std.heap.ArenaAllocator.init(gpa);
|
||||
defer tmp_arena.deinit();
|
||||
@ -3311,7 +3341,9 @@ pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index)
|
||||
/// https://github.com/ziglang/zig/issues/14307
|
||||
pub fn semaPkg(mod: *Module, pkg: *Package.Module) !void {
|
||||
const file = (try mod.importPkg(pkg)).file;
|
||||
return mod.semaFile(file);
|
||||
if (file.root_decl == .none) {
|
||||
return mod.semaFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
fn getFileRootStruct(zcu: *Zcu, decl_index: Decl.Index, namespace_index: Namespace.Index, file: *File) Allocator.Error!InternPool.Index {
|
||||
@ -3383,9 +3415,13 @@ fn getFileRootStruct(zcu: *Zcu, decl_index: Decl.Index, namespace_index: Namespa
|
||||
/// reconstructed at a new InternPool index. Otherwise, the namespace is just
|
||||
/// re-analyzed. Returns whether the decl's tyval was invalidated.
|
||||
fn semaFileUpdate(zcu: *Zcu, file: *File, type_outdated: bool) SemaError!bool {
|
||||
assert(file.root_decl != .none);
|
||||
const decl = zcu.declPtr(file.root_decl.unwrap().?);
|
||||
|
||||
const decl = zcu.declPtr(file.root_decl);
|
||||
log.debug("semaFileUpdate mod={s} sub_file_path={s} type_outdated={}", .{
|
||||
file.mod.fully_qualified_name,
|
||||
file.sub_file_path,
|
||||
type_outdated,
|
||||
});
|
||||
|
||||
if (file.status != .success_zir) {
|
||||
if (decl.analysis == .file_failure) {
|
||||
@ -3398,7 +3434,7 @@ fn semaFileUpdate(zcu: *Zcu, file: *File, type_outdated: bool) SemaError!bool {
|
||||
|
||||
if (decl.analysis == .file_failure) {
|
||||
// No struct type currently exists. Create one!
|
||||
_ = try zcu.getFileRootStruct(file.root_decl, decl.src_namespace, file);
|
||||
_ = try zcu.getFileRootStruct(file.root_decl.unwrap().?, decl.src_namespace, file);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3407,9 +3443,10 @@ fn semaFileUpdate(zcu: *Zcu, file: *File, type_outdated: bool) SemaError!bool {
|
||||
|
||||
if (type_outdated) {
|
||||
// Invalidate the existing type, reusing the decl and namespace.
|
||||
try zcu.intern_pool.remove(decl.val.toIntern());
|
||||
zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.Depender.wrap(.{ .decl = file.root_decl.unwrap().? }));
|
||||
zcu.intern_pool.remove(decl.val.toIntern());
|
||||
decl.val = undefined;
|
||||
_ = try zcu.getFileRootStruct(file.root_decl, decl.src_namespace, file);
|
||||
_ = try zcu.getFileRootStruct(file.root_decl.unwrap().?, decl.src_namespace, file);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3420,7 +3457,7 @@ fn semaFileUpdate(zcu: *Zcu, file: *File, type_outdated: bool) SemaError!bool {
|
||||
const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
|
||||
|
||||
var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len;
|
||||
extra_index += @intFromEnum(small.has_fields_len);
|
||||
extra_index += @intFromBool(small.has_fields_len);
|
||||
const decls_len = if (small.has_decls_len) blk: {
|
||||
const decls_len = file.zir.extra[extra_index];
|
||||
extra_index += 1;
|
||||
@ -3530,11 +3567,13 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
|
||||
|
||||
assert(!mod.declIsRoot(decl_index));
|
||||
|
||||
if (decl.owns_tv) {
|
||||
// We are re-analyzing an owner Decl (for a function or a namespace type).
|
||||
@panic("TODO: update owner Decl");
|
||||
if (decl.zir_decl_index == .none and decl.owns_tv) {
|
||||
// We are re-analyzing an anonymous owner Decl (for a function or a namespace type).
|
||||
return mod.semaAnonOwnerDecl(decl_index);
|
||||
}
|
||||
|
||||
log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)});
|
||||
|
||||
const decl_inst = decl.zir_decl_index.unwrap().?.resolve(ip);
|
||||
|
||||
const gpa = mod.gpa;
|
||||
@ -3827,6 +3866,42 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
|
||||
return result;
|
||||
}
|
||||
|
||||
fn semaAnonOwnerDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult {
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
|
||||
assert(decl.has_tv);
|
||||
assert(decl.owns_tv);
|
||||
|
||||
log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)});
|
||||
|
||||
switch (decl.ty.zigTypeTag(zcu)) {
|
||||
.Fn => @panic("TODO: update fn instance"),
|
||||
.Type => {},
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
// We are the owner Decl of a type, and we were marked as outdated. That means the *structure*
|
||||
// of this type changed; not just its namespace. Therefore, we need a new InternPool index.
|
||||
//
|
||||
// However, as soon as we make that, the context that created us will require re-analysis anyway
|
||||
// (as it depends on this Decl's value), meaning the `struct_decl` (or equivalent) instruction
|
||||
// will be analyzed again. Since Sema already needs to be able to reconstruct types like this,
|
||||
// why should we bother implementing it here too when the Sema logic will be hit right after?
|
||||
//
|
||||
// So instead, let's just mark this Decl as failed - so that any remaining Decls which genuinely
|
||||
// reference it (via `@This`) end up silently erroring too - and we'll let Sema make a new type
|
||||
// with a new Decl.
|
||||
//
|
||||
// Yes, this does mean that any type owner Decl has a constant value for its entire lifetime.
|
||||
zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.Depender.wrap(.{ .decl = decl_index }));
|
||||
zcu.intern_pool.remove(decl.val.toIntern());
|
||||
decl.analysis = .dependency_failure;
|
||||
return .{
|
||||
.invalidate_decl_val = true,
|
||||
.invalidate_decl_ref = true,
|
||||
};
|
||||
}
|
||||
|
||||
pub const ImportFileResult = struct {
|
||||
file: *File,
|
||||
is_new: bool,
|
||||
@ -4152,7 +4227,7 @@ pub fn scanNamespace(
|
||||
var existing_by_inst: std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Decl.Index) = .{};
|
||||
defer existing_by_inst.deinit(gpa);
|
||||
|
||||
try existing_by_inst.ensureTotalCapacity(namespace.decls.count());
|
||||
try existing_by_inst.ensureTotalCapacity(gpa, @intCast(namespace.decls.count()));
|
||||
|
||||
for (namespace.decls.keys()) |decl_index| {
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
@ -4357,7 +4432,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void
|
||||
.anon => unreachable,
|
||||
.@"comptime" => true,
|
||||
.@"usingnamespace" => a: {
|
||||
namespace.usingnamespace_set.putNoClobber(decl_index, declaration.flags.is_pub);
|
||||
namespace.usingnamespace_set.putAssumeCapacityNoClobber(decl_index, declaration.flags.is_pub);
|
||||
break :a true;
|
||||
},
|
||||
.named => false,
|
||||
@ -4533,6 +4608,11 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
|
||||
};
|
||||
defer sema.deinit();
|
||||
|
||||
// Every runtime function has a dependency on the source of the Decl it originates from.
|
||||
// It also depends on the value of its owner Decl.
|
||||
try sema.declareDependency(.{ .src_hash = decl.zir_decl_index.unwrap().? });
|
||||
try sema.declareDependency(.{ .decl_val = decl_index });
|
||||
|
||||
if (func.analysis(ip).inferred_error_set) {
|
||||
const ies = try arena.create(Sema.InferredErrorSet);
|
||||
ies.* = .{ .func = func_index };
|
||||
|
||||
105
src/Sema.zig
105
src/Sema.zig
@ -2705,6 +2705,37 @@ fn getCaptures(sema: *Sema, block: *Block, extra_index: usize, captures_len: u32
|
||||
return captures;
|
||||
}
|
||||
|
||||
/// Given an `InternPool.WipNamespaceType` or `InternPool.WipEnumType`, apply
|
||||
/// `sema.builtin_type_target_index` to it if necessary.
|
||||
fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) {
|
||||
if (sema.builtin_type_target_index == .none) return wip_ty;
|
||||
var new = wip_ty;
|
||||
new.index = sema.builtin_type_target_index;
|
||||
sema.mod.intern_pool.resolveBuiltinType(new.index, wip_ty.index);
|
||||
return new;
|
||||
}
|
||||
|
||||
/// Given a type just looked up in the `InternPool`, check whether it is
|
||||
/// considered outdated on this update. If so, remove it from the pool
|
||||
/// and return `true`.
|
||||
fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool {
|
||||
const zcu = sema.mod;
|
||||
|
||||
if (!zcu.comp.debug_incremental) return false;
|
||||
|
||||
const decl_index = Type.fromInterned(ty).getOwnerDecl(zcu);
|
||||
const decl_as_depender = InternPool.Depender.wrap(.{ .decl = decl_index });
|
||||
const was_outdated = zcu.outdated.swapRemove(decl_as_depender) or
|
||||
zcu.potentially_outdated.swapRemove(decl_as_depender);
|
||||
if (!was_outdated) return false;
|
||||
_ = zcu.outdated_ready.swapRemove(decl_as_depender);
|
||||
zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.Depender.wrap(.{ .decl = decl_index }));
|
||||
zcu.intern_pool.remove(ty);
|
||||
zcu.declPtr(decl_index).analysis = .dependency_failure;
|
||||
try zcu.markDependeeOutdated(.{ .decl_val = decl_index });
|
||||
return true;
|
||||
}
|
||||
|
||||
fn zirStructDecl(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
@ -2748,7 +2779,7 @@ fn zirStructDecl(
|
||||
}
|
||||
}
|
||||
|
||||
const wip_ty = switch (try ip.getStructType(gpa, .{
|
||||
const struct_init: InternPool.StructTypeInit = .{
|
||||
.layout = small.layout,
|
||||
.fields_len = fields_len,
|
||||
.known_non_opv = small.known_non_opv,
|
||||
@ -2763,16 +2794,14 @@ fn zirStructDecl(
|
||||
.zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst),
|
||||
.captures = captures,
|
||||
} },
|
||||
})) {
|
||||
.existing => |ty| return Air.internedToRef(ty),
|
||||
.wip => |wip| wip: {
|
||||
if (sema.builtin_type_target_index == .none) break :wip wip;
|
||||
var new = wip;
|
||||
new.index = sema.builtin_type_target_index;
|
||||
ip.resolveBuiltinType(new.index, wip.index);
|
||||
break :wip new;
|
||||
},
|
||||
};
|
||||
const wip_ty = sema.wrapWipTy(switch (try ip.getStructType(gpa, struct_init)) {
|
||||
.existing => |ty| wip: {
|
||||
if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
|
||||
break :wip (try ip.getStructType(gpa, struct_init)).wip;
|
||||
},
|
||||
.wip => |wip| wip,
|
||||
});
|
||||
errdefer wip_ty.cancel(ip);
|
||||
|
||||
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
|
||||
@ -2969,7 +2998,7 @@ fn zirEnumDecl(
|
||||
if (bag != 0) break true;
|
||||
} else false;
|
||||
|
||||
const wip_ty = switch (try ip.getEnumType(gpa, .{
|
||||
const enum_init: InternPool.EnumTypeInit = .{
|
||||
.has_namespace = true or decls_len > 0, // TODO: see below
|
||||
.has_values = any_values,
|
||||
.tag_mode = if (small.nonexhaustive)
|
||||
@ -2983,16 +3012,14 @@ fn zirEnumDecl(
|
||||
.zir_index = try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst),
|
||||
.captures = captures,
|
||||
} },
|
||||
})) {
|
||||
.wip => |wip| wip: {
|
||||
if (sema.builtin_type_target_index == .none) break :wip wip;
|
||||
var new = wip;
|
||||
new.index = sema.builtin_type_target_index;
|
||||
ip.resolveBuiltinType(new.index, wip.index);
|
||||
break :wip new;
|
||||
},
|
||||
.existing => |ty| return Air.internedToRef(ty),
|
||||
};
|
||||
const wip_ty = sema.wrapWipTy(switch (try ip.getEnumType(gpa, enum_init)) {
|
||||
.existing => |ty| wip: {
|
||||
if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
|
||||
break :wip (try ip.getEnumType(gpa, enum_init)).wip;
|
||||
},
|
||||
.wip => |wip| wip,
|
||||
});
|
||||
|
||||
// Once this is `true`, we will not delete the decl or type even upon failure, since we
|
||||
// have finished constructing the type and are in the process of analyzing it.
|
||||
@ -3230,7 +3257,7 @@ fn zirUnionDecl(
|
||||
const captures = try sema.getCaptures(block, extra_index, captures_len);
|
||||
extra_index += captures_len;
|
||||
|
||||
const wip_ty = switch (try ip.getUnionType(gpa, .{
|
||||
const union_init: InternPool.UnionTypeInit = .{
|
||||
.flags = .{
|
||||
.layout = small.layout,
|
||||
.status = .none,
|
||||
@ -3257,16 +3284,14 @@ fn zirUnionDecl(
|
||||
.zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst),
|
||||
.captures = captures,
|
||||
} },
|
||||
})) {
|
||||
.wip => |wip| wip: {
|
||||
if (sema.builtin_type_target_index == .none) break :wip wip;
|
||||
var new = wip;
|
||||
new.index = sema.builtin_type_target_index;
|
||||
ip.resolveBuiltinType(new.index, wip.index);
|
||||
break :wip new;
|
||||
},
|
||||
.existing => |ty| return Air.internedToRef(ty),
|
||||
};
|
||||
const wip_ty = sema.wrapWipTy(switch (try ip.getUnionType(gpa, union_init)) {
|
||||
.existing => |ty| wip: {
|
||||
if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
|
||||
break :wip (try ip.getUnionType(gpa, union_init)).wip;
|
||||
},
|
||||
.wip => |wip| wip,
|
||||
});
|
||||
errdefer wip_ty.cancel(ip);
|
||||
|
||||
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
|
||||
@ -3336,15 +3361,20 @@ fn zirOpaqueDecl(
|
||||
const captures = try sema.getCaptures(block, extra_index, captures_len);
|
||||
extra_index += captures_len;
|
||||
|
||||
const wip_ty = switch (try ip.getOpaqueType(gpa, .{
|
||||
const opaque_init: InternPool.OpaqueTypeInit = .{
|
||||
.has_namespace = decls_len != 0,
|
||||
.key = .{ .declared = .{
|
||||
.zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst),
|
||||
.captures = captures,
|
||||
} },
|
||||
})) {
|
||||
};
|
||||
// No `wrapWipTy` needed as no std.builtin types are opaque.
|
||||
const wip_ty = switch (try ip.getOpaqueType(gpa, opaque_init)) {
|
||||
.existing => |ty| wip: {
|
||||
if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
|
||||
break :wip (try ip.getOpaqueType(gpa, opaque_init)).wip;
|
||||
},
|
||||
.wip => |wip| wip,
|
||||
.existing => |ty| return Air.internedToRef(ty),
|
||||
};
|
||||
errdefer wip_ty.cancel(ip);
|
||||
|
||||
@ -39052,6 +39082,15 @@ fn ptrType(sema: *Sema, info: InternPool.Key.PtrType) CompileError!Type {
|
||||
|
||||
pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
|
||||
if (!sema.mod.comp.debug_incremental) return;
|
||||
|
||||
// Avoid creating dependencies on ourselves. This situation can arise when we analyze the fields
|
||||
// of a type and they use `@This()`. This dependency would be unnecessary, and in fact would
|
||||
// just result in over-analysis since `Zcu.findOutdatedToAnalyze` would never be able to resolve
|
||||
// the loop.
|
||||
if (sema.owner_func_index == .none and dependee == .decl_val and dependee.decl_val == sema.owner_decl_index) {
|
||||
return;
|
||||
}
|
||||
|
||||
const depender = InternPool.Depender.wrap(
|
||||
if (sema.owner_func_index != .none)
|
||||
.{ .func = sema.owner_func_index }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user