| author | |
| committer | |
| log | 46388d338a93a35d139866411f80115a03b30a6a |
| tree | 57cd962b1fec235a99b808d2a2877bc4bcbd5f05 |
| parent | 978fe68a65be2b5a1551ab5eafdcdbfa467ba891 |
When a type becomes outdated, there will still be lingering references
to the old index -- for instance, any declaration whose value was that
type holds a reference to that index. These references may live for an
arbitrarily long time in some cases. So, we can't just remove the type
from the pool -- the old `Index` must remain valid!
Instead, we want to preserve the old `Index`, but avoid it from ever
appearing in lookups. (It's okay if analysis of something referencing
the old `Index` does weird stuff -- such analysis are guaranteed by the
incremental compilation model to always be unreferenced.) So, we use the
new `InternPool.putKeyReplace` to replace the shard entry for this index
with the newly-created index.3 files changed, 87 insertions(+), 32 deletions(-)
src/InternPool.zig+65-6| ... | @@ -7077,6 +7077,7 @@ fn getOrPutKeyEnsuringAdditionalCapacity( | ... | @@ -7077,6 +7077,7 @@ fn getOrPutKeyEnsuringAdditionalCapacity( |
| 7077 | const index = entry.acquire(); | 7077 | const index = entry.acquire(); |
| 7078 | if (index == .none) break; | 7078 | if (index == .none) break; |
| 7079 | if (entry.hash != hash) continue; | 7079 | if (entry.hash != hash) continue; |
| 7080 | if (ip.isRemoved(index)) continue; | ||
| 7080 | if (ip.indexToKey(index).eql(key, ip)) return .{ .existing = index }; | 7081 | if (ip.indexToKey(index).eql(key, ip)) return .{ .existing = index }; |
| 7081 | } | 7082 | } |
| 7082 | shard.mutate.map.mutex.lock(); | 7083 | shard.mutate.map.mutex.lock(); |
| ... | @@ -7151,6 +7152,43 @@ fn getOrPutKeyEnsuringAdditionalCapacity( | ... | @@ -7151,6 +7152,43 @@ fn getOrPutKeyEnsuringAdditionalCapacity( |
| 7151 | .map_index = map_index, | 7152 | .map_index = map_index, |
| 7152 | } }; | 7153 | } }; |
| 7153 | } | 7154 | } |
| 7155 | /// Like `getOrPutKey`, but asserts that the key already exists, and prepares to replace | ||
| 7156 | /// its shard entry with a new `Index` anyway. After finalizing this, the old index remains | ||
| 7157 | /// valid (in that `indexToKey` and similar queries will behave as before), but it will | ||
| 7158 | /// never be returned from a lookup (`getOrPutKey` etc). | ||
| 7159 | /// This is used by incremental compilation when an existing container type is outdated. In | ||
| 7160 | /// this case, the type must be recreated at a new `InternPool.Index`, but the old index must | ||
| 7161 | /// remain valid since now-unreferenced `AnalUnit`s may retain references to it. The old index | ||
| 7162 | /// will be cleaned up when the `Zcu` undergoes garbage collection. | ||
| 7163 | fn putKeyReplace( | ||
| 7164 | ip: *InternPool, | ||
| 7165 | tid: Zcu.PerThread.Id, | ||
| 7166 | key: Key, | ||
| 7167 | ) GetOrPutKey { | ||
| 7168 | const full_hash = key.hash64(ip); | ||
| 7169 | const hash: u32 = @truncate(full_hash >> 32); | ||
| 7170 | const shard = &ip.shards[@intCast(full_hash & (ip.shards.len - 1))]; | ||
| 7171 | shard.mutate.map.mutex.lock(); | ||
| 7172 | errdefer shard.mutate.map.mutex.unlock(); | ||
| 7173 | const map = shard.shared.map; | ||
| 7174 | const map_mask = map.header().mask(); | ||
| 7175 | var map_index = hash; | ||
| 7176 | while (true) : (map_index += 1) { | ||
| 7177 | map_index &= map_mask; | ||
| 7178 | const entry = &map.entries[map_index]; | ||
| 7179 | const index = entry.value; | ||
| 7180 | assert(index != .none); // key not present | ||
| 7181 | if (entry.hash == hash and ip.indexToKey(index).eql(key, ip)) { | ||
| 7182 | break; // we found the entry to replace | ||
| 7183 | } | ||
| 7184 | } | ||
| 7185 | return .{ .new = .{ | ||
| 7186 | .ip = ip, | ||
| 7187 | .tid = tid, | ||
| 7188 | .shard = shard, | ||
| 7189 | .map_index = map_index, | ||
| 7190 | } }; | ||
| 7191 | } | ||
| 7154 | 7192 | ||
| 7155 | pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) Allocator.Error!Index { | 7193 | pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) Allocator.Error!Index { |
| 7156 | var gop = try ip.getOrPutKey(gpa, tid, key); | 7194 | var gop = try ip.getOrPutKey(gpa, tid, key); |
| ... | @@ -7990,8 +8028,11 @@ pub fn getUnionType( | ... | @@ -7990,8 +8028,11 @@ pub fn getUnionType( |
| 7990 | gpa: Allocator, | 8028 | gpa: Allocator, |
| 7991 | tid: Zcu.PerThread.Id, | 8029 | tid: Zcu.PerThread.Id, |
| 7992 | ini: UnionTypeInit, | 8030 | ini: UnionTypeInit, |
| 8031 | /// If it is known that there is an existing type with this key which is outdated, | ||
| 8032 | /// this is passed as `true`, and the type is replaced with one at a fresh index. | ||
| 8033 | replace_existing: bool, | ||
| 7993 | ) Allocator.Error!WipNamespaceType.Result { | 8034 | ) Allocator.Error!WipNamespaceType.Result { |
| 7994 | var gop = try ip.getOrPutKey(gpa, tid, .{ .union_type = switch (ini.key) { | 8035 | const key: Key = .{ .union_type = switch (ini.key) { |
| 7995 | .declared => |d| .{ .declared = .{ | 8036 | .declared => |d| .{ .declared = .{ |
| 7996 | .zir_index = d.zir_index, | 8037 | .zir_index = d.zir_index, |
| 7997 | .captures = .{ .external = d.captures }, | 8038 | .captures = .{ .external = d.captures }, |
| ... | @@ -8000,7 +8041,11 @@ pub fn getUnionType( | ... | @@ -8000,7 +8041,11 @@ pub fn getUnionType( |
| 8000 | .zir_index = r.zir_index, | 8041 | .zir_index = r.zir_index, |
| 8001 | .type_hash = r.type_hash, | 8042 | .type_hash = r.type_hash, |
| 8002 | } }, | 8043 | } }, |
| 8003 | } }); | 8044 | } }; |
| 8045 | var gop = if (replace_existing) | ||
| 8046 | ip.putKeyReplace(tid, key) | ||
| 8047 | else | ||
| 8048 | try ip.getOrPutKey(gpa, tid, key); | ||
| 8004 | defer gop.deinit(); | 8049 | defer gop.deinit(); |
| 8005 | if (gop == .existing) return .{ .existing = gop.existing }; | 8050 | if (gop == .existing) return .{ .existing = gop.existing }; |
| 8006 | 8051 | ||
| ... | @@ -8166,8 +8211,11 @@ pub fn getStructType( | ... | @@ -8166,8 +8211,11 @@ pub fn getStructType( |
| 8166 | gpa: Allocator, | 8211 | gpa: Allocator, |
| 8167 | tid: Zcu.PerThread.Id, | 8212 | tid: Zcu.PerThread.Id, |
| 8168 | ini: StructTypeInit, | 8213 | ini: StructTypeInit, |
| 8214 | /// If it is known that there is an existing type with this key which is outdated, | ||
| 8215 | /// this is passed as `true`, and the type is replaced with one at a fresh index. | ||
| 8216 | replace_existing: bool, | ||
| 8169 | ) Allocator.Error!WipNamespaceType.Result { | 8217 | ) Allocator.Error!WipNamespaceType.Result { |
| 8170 | var gop = try ip.getOrPutKey(gpa, tid, .{ .struct_type = switch (ini.key) { | 8218 | const key: Key = .{ .struct_type = switch (ini.key) { |
| 8171 | .declared => |d| .{ .declared = .{ | 8219 | .declared => |d| .{ .declared = .{ |
| 8172 | .zir_index = d.zir_index, | 8220 | .zir_index = d.zir_index, |
| 8173 | .captures = .{ .external = d.captures }, | 8221 | .captures = .{ .external = d.captures }, |
| ... | @@ -8176,7 +8224,11 @@ pub fn getStructType( | ... | @@ -8176,7 +8224,11 @@ pub fn getStructType( |
| 8176 | .zir_index = r.zir_index, | 8224 | .zir_index = r.zir_index, |
| 8177 | .type_hash = r.type_hash, | 8225 | .type_hash = r.type_hash, |
| 8178 | } }, | 8226 | } }, |
| 8179 | } }); | 8227 | } }; |
| 8228 | var gop = if (replace_existing) | ||
| 8229 | ip.putKeyReplace(tid, key) | ||
| 8230 | else | ||
| 8231 | try ip.getOrPutKey(gpa, tid, key); | ||
| 8180 | defer gop.deinit(); | 8232 | defer gop.deinit(); |
| 8181 | if (gop == .existing) return .{ .existing = gop.existing }; | 8233 | if (gop == .existing) return .{ .existing = gop.existing }; |
| 8182 | 8234 | ||
| ... | @@ -9200,8 +9252,11 @@ pub fn getEnumType( | ... | @@ -9200,8 +9252,11 @@ pub fn getEnumType( |
| 9200 | gpa: Allocator, | 9252 | gpa: Allocator, |
| 9201 | tid: Zcu.PerThread.Id, | 9253 | tid: Zcu.PerThread.Id, |
| 9202 | ini: EnumTypeInit, | 9254 | ini: EnumTypeInit, |
| 9255 | /// If it is known that there is an existing type with this key which is outdated, | ||
| 9256 | /// this is passed as `true`, and the type is replaced with one at a fresh index. | ||
| 9257 | replace_existing: bool, | ||
| 9203 | ) Allocator.Error!WipEnumType.Result { | 9258 | ) Allocator.Error!WipEnumType.Result { |
| 9204 | var gop = try ip.getOrPutKey(gpa, tid, .{ .enum_type = switch (ini.key) { | 9259 | const key: Key = .{ .enum_type = switch (ini.key) { |
| 9205 | .declared => |d| .{ .declared = .{ | 9260 | .declared => |d| .{ .declared = .{ |
| 9206 | .zir_index = d.zir_index, | 9261 | .zir_index = d.zir_index, |
| 9207 | .captures = .{ .external = d.captures }, | 9262 | .captures = .{ .external = d.captures }, |
| ... | @@ -9210,7 +9265,11 @@ pub fn getEnumType( | ... | @@ -9210,7 +9265,11 @@ pub fn getEnumType( |
| 9210 | .zir_index = r.zir_index, | 9265 | .zir_index = r.zir_index, |
| 9211 | .type_hash = r.type_hash, | 9266 | .type_hash = r.type_hash, |
| 9212 | } }, | 9267 | } }, |
| 9213 | } }); | 9268 | } }; |
| 9269 | var gop = if (replace_existing) | ||
| 9270 | ip.putKeyReplace(tid, key) | ||
| 9271 | else | ||
| 9272 | try ip.getOrPutKey(gpa, tid, key); | ||
| 9214 | defer gop.deinit(); | 9273 | defer gop.deinit(); |
| 9215 | if (gop == .existing) return .{ .existing = gop.existing }; | 9274 | if (gop == .existing) return .{ .existing = gop.existing }; |
| 9216 | 9275 |
src/Sema.zig+16-17| ... | @@ -2724,9 +2724,9 @@ fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) { | ... | @@ -2724,9 +2724,9 @@ fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) { |
| 2724 | } | 2724 | } |
| 2725 | 2725 | ||
| 2726 | /// Given a type just looked up in the `InternPool`, check whether it is | 2726 | /// Given a type just looked up in the `InternPool`, check whether it is |
| 2727 | /// considered outdated on this update. If so, remove it from the pool | 2727 | /// considered outdated on this update. If so, returns `true`, and the |
| 2728 | /// and return `true`. | 2728 | /// caller must replace the outdated type with a fresh one. |
| 2729 | fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool { | 2729 | fn checkOutdatedType(sema: *Sema, ty: InternPool.Index) !bool { |
| 2730 | const pt = sema.pt; | 2730 | const pt = sema.pt; |
| 2731 | const zcu = pt.zcu; | 2731 | const zcu = pt.zcu; |
| 2732 | const ip = &zcu.intern_pool; | 2732 | const ip = &zcu.intern_pool; |
| ... | @@ -2745,7 +2745,6 @@ fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool { | ... | @@ -2745,7 +2745,6 @@ fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool { |
| 2745 | if (!was_outdated) return false; | 2745 | if (!was_outdated) return false; |
| 2746 | _ = zcu.outdated_ready.swapRemove(cau_unit); | 2746 | _ = zcu.outdated_ready.swapRemove(cau_unit); |
| 2747 | zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, cau_unit); | 2747 | zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, cau_unit); |
| 2748 | zcu.intern_pool.remove(pt.tid, ty); | ||
| 2749 | try zcu.markDependeeOutdated(.marked_po, .{ .interned = ty }); | 2748 | try zcu.markDependeeOutdated(.marked_po, .{ .interned = ty }); |
| 2750 | return true; | 2749 | return true; |
| 2751 | } | 2750 | } |
| ... | @@ -2815,14 +2814,14 @@ fn zirStructDecl( | ... | @@ -2815,14 +2814,14 @@ fn zirStructDecl( |
| 2815 | .captures = captures, | 2814 | .captures = captures, |
| 2816 | } }, | 2815 | } }, |
| 2817 | }; | 2816 | }; |
| 2818 | const wip_ty = sema.wrapWipTy(switch (try ip.getStructType(gpa, pt.tid, struct_init)) { | 2817 | const wip_ty = sema.wrapWipTy(switch (try ip.getStructType(gpa, pt.tid, struct_init, false)) { |
| 2819 | .existing => |ty| wip: { | 2818 | .existing => |ty| wip: { |
| 2820 | if (!try sema.maybeRemoveOutdatedType(ty)) { | 2819 | if (!try sema.checkOutdatedType(ty)) { |
| 2821 | try sema.declareDependency(.{ .interned = ty }); | 2820 | try sema.declareDependency(.{ .interned = ty }); |
| 2822 | try sema.addTypeReferenceEntry(src, ty); | 2821 | try sema.addTypeReferenceEntry(src, ty); |
| 2823 | return Air.internedToRef(ty); | 2822 | return Air.internedToRef(ty); |
| 2824 | } | 2823 | } |
| 2825 | break :wip (try ip.getStructType(gpa, pt.tid, struct_init)).wip; | 2824 | break :wip (try ip.getStructType(gpa, pt.tid, struct_init, true)).wip; |
| 2826 | }, | 2825 | }, |
| 2827 | .wip => |wip| wip, | 2826 | .wip => |wip| wip, |
| 2828 | }); | 2827 | }); |
| ... | @@ -3041,14 +3040,14 @@ fn zirEnumDecl( | ... | @@ -3041,14 +3040,14 @@ fn zirEnumDecl( |
| 3041 | .captures = captures, | 3040 | .captures = captures, |
| 3042 | } }, | 3041 | } }, |
| 3043 | }; | 3042 | }; |
| 3044 | const wip_ty = sema.wrapWipTy(switch (try ip.getEnumType(gpa, pt.tid, enum_init)) { | 3043 | const wip_ty = sema.wrapWipTy(switch (try ip.getEnumType(gpa, pt.tid, enum_init, false)) { |
| 3045 | .existing => |ty| wip: { | 3044 | .existing => |ty| wip: { |
| 3046 | if (!try sema.maybeRemoveOutdatedType(ty)) { | 3045 | if (!try sema.checkOutdatedType(ty)) { |
| 3047 | try sema.declareDependency(.{ .interned = ty }); | 3046 | try sema.declareDependency(.{ .interned = ty }); |
| 3048 | try sema.addTypeReferenceEntry(src, ty); | 3047 | try sema.addTypeReferenceEntry(src, ty); |
| 3049 | return Air.internedToRef(ty); | 3048 | return Air.internedToRef(ty); |
| 3050 | } | 3049 | } |
| 3051 | break :wip (try ip.getEnumType(gpa, pt.tid, enum_init)).wip; | 3050 | break :wip (try ip.getEnumType(gpa, pt.tid, enum_init, true)).wip; |
| 3052 | }, | 3051 | }, |
| 3053 | .wip => |wip| wip, | 3052 | .wip => |wip| wip, |
| 3054 | }); | 3053 | }); |
| ... | @@ -3311,14 +3310,14 @@ fn zirUnionDecl( | ... | @@ -3311,14 +3310,14 @@ fn zirUnionDecl( |
| 3311 | .captures = captures, | 3310 | .captures = captures, |
| 3312 | } }, | 3311 | } }, |
| 3313 | }; | 3312 | }; |
| 3314 | const wip_ty = sema.wrapWipTy(switch (try ip.getUnionType(gpa, pt.tid, union_init)) { | 3313 | const wip_ty = sema.wrapWipTy(switch (try ip.getUnionType(gpa, pt.tid, union_init, false)) { |
| 3315 | .existing => |ty| wip: { | 3314 | .existing => |ty| wip: { |
| 3316 | if (!try sema.maybeRemoveOutdatedType(ty)) { | 3315 | if (!try sema.checkOutdatedType(ty)) { |
| 3317 | try sema.declareDependency(.{ .interned = ty }); | 3316 | try sema.declareDependency(.{ .interned = ty }); |
| 3318 | try sema.addTypeReferenceEntry(src, ty); | 3317 | try sema.addTypeReferenceEntry(src, ty); |
| 3319 | return Air.internedToRef(ty); | 3318 | return Air.internedToRef(ty); |
| 3320 | } | 3319 | } |
| 3321 | break :wip (try ip.getUnionType(gpa, pt.tid, union_init)).wip; | 3320 | break :wip (try ip.getUnionType(gpa, pt.tid, union_init, true)).wip; |
| 3322 | }, | 3321 | }, |
| 3323 | .wip => |wip| wip, | 3322 | .wip => |wip| wip, |
| 3324 | }); | 3323 | }); |
| ... | @@ -3407,7 +3406,7 @@ fn zirOpaqueDecl( | ... | @@ -3407,7 +3406,7 @@ fn zirOpaqueDecl( |
| 3407 | }; | 3406 | }; |
| 3408 | // No `wrapWipTy` needed as no std.builtin types are opaque. | 3407 | // No `wrapWipTy` needed as no std.builtin types are opaque. |
| 3409 | const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, opaque_init)) { | 3408 | const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, opaque_init)) { |
| 3410 | // No `maybeRemoveOutdatedType` as opaque types are never outdated. | 3409 | // No `checkOutdatedType` as opaque types are never outdated. |
| 3411 | .existing => |ty| { | 3410 | .existing => |ty| { |
| 3412 | try sema.addTypeReferenceEntry(src, ty); | 3411 | try sema.addTypeReferenceEntry(src, ty); |
| 3413 | return Air.internedToRef(ty); | 3412 | return Air.internedToRef(ty); |
| ... | @@ -22054,7 +22053,7 @@ fn reifyEnum( | ... | @@ -22054,7 +22053,7 @@ fn reifyEnum( |
| 22054 | .zir_index = tracked_inst, | 22053 | .zir_index = tracked_inst, |
| 22055 | .type_hash = hasher.final(), | 22054 | .type_hash = hasher.final(), |
| 22056 | } }, | 22055 | } }, |
| 22057 | })) { | 22056 | }, false)) { |
| 22058 | .wip => |wip| wip, | 22057 | .wip => |wip| wip, |
| 22059 | .existing => |ty| { | 22058 | .existing => |ty| { |
| 22060 | try sema.declareDependency(.{ .interned = ty }); | 22059 | try sema.declareDependency(.{ .interned = ty }); |
| ... | @@ -22224,7 +22223,7 @@ fn reifyUnion( | ... | @@ -22224,7 +22223,7 @@ fn reifyUnion( |
| 22224 | .zir_index = tracked_inst, | 22223 | .zir_index = tracked_inst, |
| 22225 | .type_hash = hasher.final(), | 22224 | .type_hash = hasher.final(), |
| 22226 | } }, | 22225 | } }, |
| 22227 | })) { | 22226 | }, false)) { |
| 22228 | .wip => |wip| wip, | 22227 | .wip => |wip| wip, |
| 22229 | .existing => |ty| { | 22228 | .existing => |ty| { |
| 22230 | try sema.declareDependency(.{ .interned = ty }); | 22229 | try sema.declareDependency(.{ .interned = ty }); |
| ... | @@ -22494,7 +22493,7 @@ fn reifyStruct( | ... | @@ -22494,7 +22493,7 @@ fn reifyStruct( |
| 22494 | .zir_index = tracked_inst, | 22493 | .zir_index = tracked_inst, |
| 22495 | .type_hash = hasher.final(), | 22494 | .type_hash = hasher.final(), |
| 22496 | } }, | 22495 | } }, |
| 22497 | })) { | 22496 | }, false)) { |
| 22498 | .wip => |wip| wip, | 22497 | .wip => |wip| wip, |
| 22499 | .existing => |ty| { | 22498 | .existing => |ty| { |
| 22500 | try sema.declareDependency(.{ .interned = ty }); | 22499 | try sema.declareDependency(.{ .interned = ty }); |
src/Zcu/PerThread.zig+6-9| ... | @@ -925,6 +925,7 @@ fn createFileRootStruct( | ... | @@ -925,6 +925,7 @@ fn createFileRootStruct( |
| 925 | pt: Zcu.PerThread, | 925 | pt: Zcu.PerThread, |
| 926 | file_index: Zcu.File.Index, | 926 | file_index: Zcu.File.Index, |
| 927 | namespace_index: Zcu.Namespace.Index, | 927 | namespace_index: Zcu.Namespace.Index, |
| 928 | replace_existing: bool, | ||
| 928 | ) Allocator.Error!InternPool.Index { | 929 | ) Allocator.Error!InternPool.Index { |
| 929 | const zcu = pt.zcu; | 930 | const zcu = pt.zcu; |
| 930 | const gpa = zcu.gpa; | 931 | const gpa = zcu.gpa; |
| ... | @@ -968,7 +969,7 @@ fn createFileRootStruct( | ... | @@ -968,7 +969,7 @@ fn createFileRootStruct( |
| 968 | .zir_index = tracked_inst, | 969 | .zir_index = tracked_inst, |
| 969 | .captures = &.{}, | 970 | .captures = &.{}, |
| 970 | } }, | 971 | } }, |
| 971 | })) { | 972 | }, replace_existing)) { |
| 972 | .existing => unreachable, // we wouldn't be analysing the file root if this type existed | 973 | .existing => unreachable, // we wouldn't be analysing the file root if this type existed |
| 973 | .wip => |wip| wip, | 974 | .wip => |wip| wip, |
| 974 | }; | 975 | }; |
| ... | @@ -1023,8 +1024,7 @@ fn recreateFileRoot(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError | ... | @@ -1023,8 +1024,7 @@ fn recreateFileRoot(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError |
| 1023 | zcu.gpa, | 1024 | zcu.gpa, |
| 1024 | InternPool.AnalUnit.wrap(.{ .cau = file_root_type_cau }), | 1025 | InternPool.AnalUnit.wrap(.{ .cau = file_root_type_cau }), |
| 1025 | ); | 1026 | ); |
| 1026 | ip.remove(pt.tid, file_root_type); | 1027 | _ = try pt.createFileRootStruct(file_index, namespace_index, true); |
| 1027 | _ = try pt.createFileRootStruct(file_index, namespace_index); | ||
| 1028 | } | 1028 | } |
| 1029 | 1029 | ||
| 1030 | /// Re-scan the namespace of a file's root struct type on an incremental update. | 1030 | /// Re-scan the namespace of a file's root struct type on an incremental update. |
| ... | @@ -1062,8 +1062,6 @@ fn updateFileNamespace(pt: Zcu.PerThread, file_index: Zcu.File.Index) Allocator. | ... | @@ -1062,8 +1062,6 @@ fn updateFileNamespace(pt: Zcu.PerThread, file_index: Zcu.File.Index) Allocator. |
| 1062 | try pt.scanNamespace(namespace_index, decls); | 1062 | try pt.scanNamespace(namespace_index, decls); |
| 1063 | } | 1063 | } |
| 1064 | 1064 | ||
| 1065 | /// Regardless of the file status, will create a `Decl` if none exists so that we can track | ||
| 1066 | /// dependencies and re-analyze when the file becomes outdated. | ||
| 1067 | fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { | 1065 | fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { |
| 1068 | const tracy = trace(@src()); | 1066 | const tracy = trace(@src()); |
| 1069 | defer tracy.end(); | 1067 | defer tracy.end(); |
| ... | @@ -1083,7 +1081,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { | ... | @@ -1083,7 +1081,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { |
| 1083 | .owner_type = undefined, // set in `createFileRootStruct` | 1081 | .owner_type = undefined, // set in `createFileRootStruct` |
| 1084 | .file_scope = file_index, | 1082 | .file_scope = file_index, |
| 1085 | }); | 1083 | }); |
| 1086 | const struct_ty = try pt.createFileRootStruct(file_index, new_namespace_index); | 1084 | const struct_ty = try pt.createFileRootStruct(file_index, new_namespace_index, false); |
| 1087 | errdefer zcu.intern_pool.remove(pt.tid, struct_ty); | 1085 | errdefer zcu.intern_pool.remove(pt.tid, struct_ty); |
| 1088 | 1086 | ||
| 1089 | switch (zcu.comp.cache_use) { | 1087 | switch (zcu.comp.cache_use) { |
| ... | @@ -1153,11 +1151,10 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { | ... | @@ -1153,11 +1151,10 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { |
| 1153 | // This declaration has no value so is definitely not a std.builtin type. | 1151 | // This declaration has no value so is definitely not a std.builtin type. |
| 1154 | break :ip_index .none; | 1152 | break :ip_index .none; |
| 1155 | }, | 1153 | }, |
| 1156 | .type => |ty| { | 1154 | .type => { |
| 1157 | // This is an incremental update, and this type is being re-analyzed because it is outdated. | 1155 | // This is an incremental update, and this type is being re-analyzed because it is outdated. |
| 1158 | // The type must be recreated at a new `InternPool.Index`. | 1156 | // The type must be recreated at a new `InternPool.Index`. |
| 1159 | // Remove it from the InternPool and mark it outdated so that creation sites are re-analyzed. | 1157 | // Mark it outdated so that creation sites are re-analyzed. |
| 1160 | ip.remove(pt.tid, ty); | ||
| 1161 | return .{ | 1158 | return .{ |
| 1162 | .invalidate_decl_val = true, | 1159 | .invalidate_decl_val = true, |
| 1163 | .invalidate_decl_ref = true, | 1160 | .invalidate_decl_ref = true, |