authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-03-09 11:53:06+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-03-14 07:40:07+00:00
log1421d329a3bbe4891eda8f234139be787fefcd2f
tree3439ccd40fe2b59801410d792ab9ad3f62f397bc
parent7ba8641d19b719c11c0f6177fb28fa098a769e1f
signaturelock-open Commit is signed but in an unrecognized format.

compiler: progress towards incremental

Most basic re-analysis logic is now in place. Trivial updates are hitting linker assertions.

3 files changed, 175 insertions(+), 56 deletions(-)

src/InternPool.zig+2-2
......@@ -7103,7 +7103,7 @@ pub fn getGeneratedTagEnumType(ip: *InternPool, gpa: Allocator, ini: GeneratedTa
71037103 return @enumFromInt(gop.index);
71047104}
71057105
7106pub const OpaqueTypeIni = struct {
7106pub const OpaqueTypeInit = struct {
71077107 has_namespace: bool,
71087108 key: union(enum) {
71097109 declared: struct {
......@@ -7117,7 +7117,7 @@ pub const OpaqueTypeIni = struct {
71177117 },
71187118};
71197119
7120pub fn getOpaqueType(ip: *InternPool, gpa: Allocator, ini: OpaqueTypeIni) Allocator.Error!WipNamespaceType.Result {
7120pub fn getOpaqueType(ip: *InternPool, gpa: Allocator, ini: OpaqueTypeInit) Allocator.Error!WipNamespaceType.Result {
71217121 const adapter: KeyAdapter = .{ .intern_pool = ip };
71227122 const gop = try ip.map.getOrPutAdapted(gpa, Key{ .opaque_type = switch (ini.key) {
71237123 .declared => |d| .{ .declared = .{
src/Module.zig+101-21
......@@ -762,14 +762,14 @@ pub const Namespace = struct {
762762 zcu: *Zcu,
763763
764764 pub fn hash(ctx: @This(), decl_index: Decl.Index) u32 {
765 const decl = ctx.module.declPtr(decl_index);
765 const decl = ctx.zcu.declPtr(decl_index);
766766 return std.hash.uint32(@intFromEnum(decl.name));
767767 }
768768
769769 pub fn eql(ctx: @This(), a_decl_index: Decl.Index, b_decl_index: Decl.Index, b_index: usize) bool {
770770 _ = b_index;
771 const a_decl = ctx.module.declPtr(a_decl_index);
772 const b_decl = ctx.module.declPtr(b_decl_index);
771 const a_decl = ctx.zcu.declPtr(a_decl_index);
772 const b_decl = ctx.zcu.declPtr(b_decl_index);
773773 return a_decl.name == b_decl.name;
774774 }
775775 };
......@@ -2655,7 +2655,7 @@ pub fn markDependeeOutdated(zcu: *Zcu, dependee: InternPool.Dependee) !void {
26552655 if (opt_po_entry) |e| e.value else 0,
26562656 );
26572657 log.debug("outdated: {}", .{depender});
2658 if (opt_po_entry != null) {
2658 if (opt_po_entry == null) {
26592659 // This is a new entry with no PO dependencies.
26602660 try zcu.outdated_ready.put(zcu.gpa, depender, {});
26612661 }
......@@ -2989,10 +2989,10 @@ pub fn mapOldZirToNew(
29892989
29902990/// Like `ensureDeclAnalyzed`, but the Decl is a file's root Decl.
29912991pub fn ensureFileAnalyzed(zcu: *Zcu, file: *File) SemaError!void {
2992 if (file.root_decl == .none) {
2993 return zcu.semaFile(file);
2992 if (file.root_decl.unwrap()) |existing_root| {
2993 return zcu.ensureDeclAnalyzed(existing_root);
29942994 } else {
2995 return zcu.ensureDeclAnalyzed(file.root_decl);
2995 return zcu.semaFile(file);
29962996 }
29972997}
29982998
......@@ -3006,6 +3006,11 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
30063006
30073007 const decl = mod.declPtr(decl_index);
30083008
3009 log.debug("ensureDeclAnalyzed '{d}' (name '{}')", .{
3010 @intFromEnum(decl_index),
3011 decl.name.fmt(&mod.intern_pool),
3012 });
3013
30093014 // Determine whether or not this Decl is outdated, i.e. requires re-analysis
30103015 // even if `complete`. If a Decl is PO, we pessismistically assume that it
30113016 // *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 {
30993104 // TODO: we do not yet have separate dependencies for decl values vs types.
31003105 if (decl_was_outdated) {
31013106 if (sema_result.invalidate_decl_val or sema_result.invalidate_decl_ref) {
3107 log.debug("Decl tv invalidated ('{d}')", .{@intFromEnum(decl_index)});
31023108 // This dependency was marked as PO, meaning dependees were waiting
31033109 // on its analysis result, and it has turned out to be outdated.
31043110 // Update dependees accordingly.
31053111 try mod.markDependeeOutdated(.{ .decl_val = decl_index });
31063112 } else {
3113 log.debug("Decl tv up-to-date ('{d}')", .{@intFromEnum(decl_index)});
31073114 // This dependency was previously PO, but turned out to be up-to-date.
31083115 // We do not need to queue successive analysis.
31093116 try mod.markPoDependeeUpToDate(.{ .decl_val = decl_index });
......@@ -3115,11 +3122,31 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError
31153122 const tracy = trace(@src());
31163123 defer tracy.end();
31173124
3125 const gpa = zcu.gpa;
31183126 const ip = &zcu.intern_pool;
31193127 const func = zcu.funcInfo(func_index);
31203128 const decl_index = func.owner_decl;
31213129 const decl = zcu.declPtr(decl_index);
31223130
3131 log.debug("ensureFuncBodyAnalyzed '{d}' (instance of '{}')", .{
3132 @intFromEnum(func_index),
3133 decl.name.fmt(ip),
3134 });
3135
3136 // First, our owner decl must be up-to-date. This will always be the case
3137 // during the first update, but may not on successive updates if we happen
3138 // to get analyzed before our parent decl.
3139 try zcu.ensureDeclAnalyzed(decl_index);
3140
3141 // On an update, it's possible this function changed such that our owner
3142 // decl now refers to a different function, making this one orphaned. If
3143 // that's the case, we should remove this function from the binary.
3144 if (decl.val.ip_index != func_index) {
3145 ip.removeDependenciesForDepender(gpa, InternPool.Depender.wrap(.{ .func = func_index }));
3146 ip.remove(func_index);
3147 @panic("TODO: remove orphaned function from binary");
3148 }
3149
31233150 switch (decl.analysis) {
31243151 .unreferenced => unreachable,
31253152 .in_progress => unreachable,
......@@ -3143,7 +3170,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError
31433170 }
31443171
31453172 switch (func.analysis(ip).state) {
3146 .success,
3173 .success => if (!was_outdated) return,
31473174 .sema_failure,
31483175 .dependency_failure,
31493176 .codegen_failure,
......@@ -3153,7 +3180,10 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError
31533180 .inline_only => unreachable, // don't queue work for this
31543181 }
31553182
3156 const gpa = zcu.gpa;
3183 log.debug("analyze and generate fn body '{d}'; reason='{s}'", .{
3184 @intFromEnum(func_index),
3185 if (was_outdated) "outdated" else "never analyzed",
3186 });
31573187
31583188 var tmp_arena = std.heap.ArenaAllocator.init(gpa);
31593189 defer tmp_arena.deinit();
......@@ -3311,7 +3341,9 @@ pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index)
33113341/// https://github.com/ziglang/zig/issues/14307
33123342pub fn semaPkg(mod: *Module, pkg: *Package.Module) !void {
33133343 const file = (try mod.importPkg(pkg)).file;
3314 return mod.semaFile(file);
3344 if (file.root_decl == .none) {
3345 return mod.semaFile(file);
3346 }
33153347}
33163348
33173349fn 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
33833415/// reconstructed at a new InternPool index. Otherwise, the namespace is just
33843416/// re-analyzed. Returns whether the decl's tyval was invalidated.
33853417fn semaFileUpdate(zcu: *Zcu, file: *File, type_outdated: bool) SemaError!bool {
3386 assert(file.root_decl != .none);
3418 const decl = zcu.declPtr(file.root_decl.unwrap().?);
33873419
3388 const decl = zcu.declPtr(file.root_decl);
3420 log.debug("semaFileUpdate mod={s} sub_file_path={s} type_outdated={}", .{
3421 file.mod.fully_qualified_name,
3422 file.sub_file_path,
3423 type_outdated,
3424 });
33893425
33903426 if (file.status != .success_zir) {
33913427 if (decl.analysis == .file_failure) {
......@@ -3398,7 +3434,7 @@ fn semaFileUpdate(zcu: *Zcu, file: *File, type_outdated: bool) SemaError!bool {
33983434
33993435 if (decl.analysis == .file_failure) {
34003436 // No struct type currently exists. Create one!
3401 _ = try zcu.getFileRootStruct(file.root_decl, decl.src_namespace, file);
3437 _ = try zcu.getFileRootStruct(file.root_decl.unwrap().?, decl.src_namespace, file);
34023438 return true;
34033439 }
34043440
......@@ -3407,9 +3443,10 @@ fn semaFileUpdate(zcu: *Zcu, file: *File, type_outdated: bool) SemaError!bool {
34073443
34083444 if (type_outdated) {
34093445 // Invalidate the existing type, reusing the decl and namespace.
3410 try zcu.intern_pool.remove(decl.val.toIntern());
3446 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.Depender.wrap(.{ .decl = file.root_decl.unwrap().? }));
3447 zcu.intern_pool.remove(decl.val.toIntern());
34113448 decl.val = undefined;
3412 _ = try zcu.getFileRootStruct(file.root_decl, decl.src_namespace, file);
3449 _ = try zcu.getFileRootStruct(file.root_decl.unwrap().?, decl.src_namespace, file);
34133450 return true;
34143451 }
34153452
......@@ -3420,7 +3457,7 @@ fn semaFileUpdate(zcu: *Zcu, file: *File, type_outdated: bool) SemaError!bool {
34203457 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
34213458
34223459 var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len;
3423 extra_index += @intFromEnum(small.has_fields_len);
3460 extra_index += @intFromBool(small.has_fields_len);
34243461 const decls_len = if (small.has_decls_len) blk: {
34253462 const decls_len = file.zir.extra[extra_index];
34263463 extra_index += 1;
......@@ -3530,11 +3567,13 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
35303567
35313568 assert(!mod.declIsRoot(decl_index));
35323569
3533 if (decl.owns_tv) {
3534 // We are re-analyzing an owner Decl (for a function or a namespace type).
3535 @panic("TODO: update owner Decl");
3570 if (decl.zir_decl_index == .none and decl.owns_tv) {
3571 // We are re-analyzing an anonymous owner Decl (for a function or a namespace type).
3572 return mod.semaAnonOwnerDecl(decl_index);
35363573 }
35373574
3575 log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)});
3576
35383577 const decl_inst = decl.zir_decl_index.unwrap().?.resolve(ip);
35393578
35403579 const gpa = mod.gpa;
......@@ -3827,6 +3866,42 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
38273866 return result;
38283867}
38293868
3869fn semaAnonOwnerDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult {
3870 const decl = zcu.declPtr(decl_index);
3871
3872 assert(decl.has_tv);
3873 assert(decl.owns_tv);
3874
3875 log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)});
3876
3877 switch (decl.ty.zigTypeTag(zcu)) {
3878 .Fn => @panic("TODO: update fn instance"),
3879 .Type => {},
3880 else => unreachable,
3881 }
3882
3883 // We are the owner Decl of a type, and we were marked as outdated. That means the *structure*
3884 // of this type changed; not just its namespace. Therefore, we need a new InternPool index.
3885 //
3886 // However, as soon as we make that, the context that created us will require re-analysis anyway
3887 // (as it depends on this Decl's value), meaning the `struct_decl` (or equivalent) instruction
3888 // will be analyzed again. Since Sema already needs to be able to reconstruct types like this,
3889 // why should we bother implementing it here too when the Sema logic will be hit right after?
3890 //
3891 // So instead, let's just mark this Decl as failed - so that any remaining Decls which genuinely
3892 // reference it (via `@This`) end up silently erroring too - and we'll let Sema make a new type
3893 // with a new Decl.
3894 //
3895 // Yes, this does mean that any type owner Decl has a constant value for its entire lifetime.
3896 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.Depender.wrap(.{ .decl = decl_index }));
3897 zcu.intern_pool.remove(decl.val.toIntern());
3898 decl.analysis = .dependency_failure;
3899 return .{
3900 .invalidate_decl_val = true,
3901 .invalidate_decl_ref = true,
3902 };
3903}
3904
38303905pub const ImportFileResult = struct {
38313906 file: *File,
38323907 is_new: bool,
......@@ -4152,7 +4227,7 @@ pub fn scanNamespace(
41524227 var existing_by_inst: std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Decl.Index) = .{};
41534228 defer existing_by_inst.deinit(gpa);
41544229
4155 try existing_by_inst.ensureTotalCapacity(namespace.decls.count());
4230 try existing_by_inst.ensureTotalCapacity(gpa, @intCast(namespace.decls.count()));
41564231
41574232 for (namespace.decls.keys()) |decl_index| {
41584233 const decl = zcu.declPtr(decl_index);
......@@ -4357,7 +4432,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void
43574432 .anon => unreachable,
43584433 .@"comptime" => true,
43594434 .@"usingnamespace" => a: {
4360 namespace.usingnamespace_set.putNoClobber(decl_index, declaration.flags.is_pub);
4435 namespace.usingnamespace_set.putAssumeCapacityNoClobber(decl_index, declaration.flags.is_pub);
43614436 break :a true;
43624437 },
43634438 .named => false,
......@@ -4533,6 +4608,11 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
45334608 };
45344609 defer sema.deinit();
45354610
4611 // Every runtime function has a dependency on the source of the Decl it originates from.
4612 // It also depends on the value of its owner Decl.
4613 try sema.declareDependency(.{ .src_hash = decl.zir_decl_index.unwrap().? });
4614 try sema.declareDependency(.{ .decl_val = decl_index });
4615
45364616 if (func.analysis(ip).inferred_error_set) {
45374617 const ies = try arena.create(Sema.InferredErrorSet);
45384618 ies.* = .{ .func = func_index };
src/Sema.zig+72-33
......@@ -2705,6 +2705,37 @@ fn getCaptures(sema: *Sema, block: *Block, extra_index: usize, captures_len: u32
27052705 return captures;
27062706}
27072707
2708/// Given an `InternPool.WipNamespaceType` or `InternPool.WipEnumType`, apply
2709/// `sema.builtin_type_target_index` to it if necessary.
2710fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) {
2711 if (sema.builtin_type_target_index == .none) return wip_ty;
2712 var new = wip_ty;
2713 new.index = sema.builtin_type_target_index;
2714 sema.mod.intern_pool.resolveBuiltinType(new.index, wip_ty.index);
2715 return new;
2716}
2717
2718/// Given a type just looked up in the `InternPool`, check whether it is
2719/// considered outdated on this update. If so, remove it from the pool
2720/// and return `true`.
2721fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool {
2722 const zcu = sema.mod;
2723
2724 if (!zcu.comp.debug_incremental) return false;
2725
2726 const decl_index = Type.fromInterned(ty).getOwnerDecl(zcu);
2727 const decl_as_depender = InternPool.Depender.wrap(.{ .decl = decl_index });
2728 const was_outdated = zcu.outdated.swapRemove(decl_as_depender) or
2729 zcu.potentially_outdated.swapRemove(decl_as_depender);
2730 if (!was_outdated) return false;
2731 _ = zcu.outdated_ready.swapRemove(decl_as_depender);
2732 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.Depender.wrap(.{ .decl = decl_index }));
2733 zcu.intern_pool.remove(ty);
2734 zcu.declPtr(decl_index).analysis = .dependency_failure;
2735 try zcu.markDependeeOutdated(.{ .decl_val = decl_index });
2736 return true;
2737}
2738
27082739fn zirStructDecl(
27092740 sema: *Sema,
27102741 block: *Block,
......@@ -2748,7 +2779,7 @@ fn zirStructDecl(
27482779 }
27492780 }
27502781
2751 const wip_ty = switch (try ip.getStructType(gpa, .{
2782 const struct_init: InternPool.StructTypeInit = .{
27522783 .layout = small.layout,
27532784 .fields_len = fields_len,
27542785 .known_non_opv = small.known_non_opv,
......@@ -2763,16 +2794,14 @@ fn zirStructDecl(
27632794 .zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst),
27642795 .captures = captures,
27652796 } },
2766 })) {
2767 .existing => |ty| return Air.internedToRef(ty),
2768 .wip => |wip| wip: {
2769 if (sema.builtin_type_target_index == .none) break :wip wip;
2770 var new = wip;
2771 new.index = sema.builtin_type_target_index;
2772 ip.resolveBuiltinType(new.index, wip.index);
2773 break :wip new;
2774 },
27752797 };
2798 const wip_ty = sema.wrapWipTy(switch (try ip.getStructType(gpa, struct_init)) {
2799 .existing => |ty| wip: {
2800 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
2801 break :wip (try ip.getStructType(gpa, struct_init)).wip;
2802 },
2803 .wip => |wip| wip,
2804 });
27762805 errdefer wip_ty.cancel(ip);
27772806
27782807 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
......@@ -2969,7 +2998,7 @@ fn zirEnumDecl(
29692998 if (bag != 0) break true;
29702999 } else false;
29713000
2972 const wip_ty = switch (try ip.getEnumType(gpa, .{
3001 const enum_init: InternPool.EnumTypeInit = .{
29733002 .has_namespace = true or decls_len > 0, // TODO: see below
29743003 .has_values = any_values,
29753004 .tag_mode = if (small.nonexhaustive)
......@@ -2983,16 +3012,14 @@ fn zirEnumDecl(
29833012 .zir_index = try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst),
29843013 .captures = captures,
29853014 } },
2986 })) {
2987 .wip => |wip| wip: {
2988 if (sema.builtin_type_target_index == .none) break :wip wip;
2989 var new = wip;
2990 new.index = sema.builtin_type_target_index;
2991 ip.resolveBuiltinType(new.index, wip.index);
2992 break :wip new;
2993 },
2994 .existing => |ty| return Air.internedToRef(ty),
29953015 };
3016 const wip_ty = sema.wrapWipTy(switch (try ip.getEnumType(gpa, enum_init)) {
3017 .existing => |ty| wip: {
3018 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
3019 break :wip (try ip.getEnumType(gpa, enum_init)).wip;
3020 },
3021 .wip => |wip| wip,
3022 });
29963023
29973024 // Once this is `true`, we will not delete the decl or type even upon failure, since we
29983025 // have finished constructing the type and are in the process of analyzing it.
......@@ -3230,7 +3257,7 @@ fn zirUnionDecl(
32303257 const captures = try sema.getCaptures(block, extra_index, captures_len);
32313258 extra_index += captures_len;
32323259
3233 const wip_ty = switch (try ip.getUnionType(gpa, .{
3260 const union_init: InternPool.UnionTypeInit = .{
32343261 .flags = .{
32353262 .layout = small.layout,
32363263 .status = .none,
......@@ -3257,16 +3284,14 @@ fn zirUnionDecl(
32573284 .zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst),
32583285 .captures = captures,
32593286 } },
3260 })) {
3261 .wip => |wip| wip: {
3262 if (sema.builtin_type_target_index == .none) break :wip wip;
3263 var new = wip;
3264 new.index = sema.builtin_type_target_index;
3265 ip.resolveBuiltinType(new.index, wip.index);
3266 break :wip new;
3267 },
3268 .existing => |ty| return Air.internedToRef(ty),
32693287 };
3288 const wip_ty = sema.wrapWipTy(switch (try ip.getUnionType(gpa, union_init)) {
3289 .existing => |ty| wip: {
3290 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
3291 break :wip (try ip.getUnionType(gpa, union_init)).wip;
3292 },
3293 .wip => |wip| wip,
3294 });
32703295 errdefer wip_ty.cancel(ip);
32713296
32723297 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
......@@ -3336,15 +3361,20 @@ fn zirOpaqueDecl(
33363361 const captures = try sema.getCaptures(block, extra_index, captures_len);
33373362 extra_index += captures_len;
33383363
3339 const wip_ty = switch (try ip.getOpaqueType(gpa, .{
3364 const opaque_init: InternPool.OpaqueTypeInit = .{
33403365 .has_namespace = decls_len != 0,
33413366 .key = .{ .declared = .{
33423367 .zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst),
33433368 .captures = captures,
33443369 } },
3345 })) {
3370 };
3371 // No `wrapWipTy` needed as no std.builtin types are opaque.
3372 const wip_ty = switch (try ip.getOpaqueType(gpa, opaque_init)) {
3373 .existing => |ty| wip: {
3374 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
3375 break :wip (try ip.getOpaqueType(gpa, opaque_init)).wip;
3376 },
33463377 .wip => |wip| wip,
3347 .existing => |ty| return Air.internedToRef(ty),
33483378 };
33493379 errdefer wip_ty.cancel(ip);
33503380
......@@ -39052,6 +39082,15 @@ fn ptrType(sema: *Sema, info: InternPool.Key.PtrType) CompileError!Type {
3905239082
3905339083pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
3905439084 if (!sema.mod.comp.debug_incremental) return;
39085
39086 // Avoid creating dependencies on ourselves. This situation can arise when we analyze the fields
39087 // of a type and they use `@This()`. This dependency would be unnecessary, and in fact would
39088 // just result in over-analysis since `Zcu.findOutdatedToAnalyze` would never be able to resolve
39089 // the loop.
39090 if (sema.owner_func_index == .none and dependee == .decl_val and dependee.decl_val == sema.owner_decl_index) {
39091 return;
39092 }
39093
3905539094 const depender = InternPool.Depender.wrap(
3905639095 if (sema.owner_func_index != .none)
3905739096 .{ .func = sema.owner_func_index }