aboutsummaryrefslogtreecommitdiff
path: root/src/InternPool.zig
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2024-10-16 15:56:48 +0100
committermlugg <mlugg@mlugg.co.uk>2024-10-16 16:30:36 +0100
commit22539783ad15be3028ed07983eb8e23910171f11 (patch)
tree0ace6676df00397e4ca4df098013220f95e85bf7 /src/InternPool.zig
parentc6842b58d488c236aca74dea82082eec365eb117 (diff)
downloadzig-22539783ad15be3028ed07983eb8e23910171f11.tar.gz
zig-22539783ad15be3028ed07983eb8e23910171f11.zip
incremental: introduce `file` dependencies to handle AstGen failures
The re-analysis here is a little coarse; it'd be nice in the future to have a way for an AstGen failure to preserve *all* analysis which depends on the last success, and just hide the compile errors which depend on it somehow. But I'm not sure how we'd achieve that, so this works fine for now. Resolves: #21223
Diffstat (limited to 'src/InternPool.zig')
-rw-r--r--src/InternPool.zig12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/InternPool.zig b/src/InternPool.zig
index f41f780e0a..4315855d83 100644
--- a/src/InternPool.zig
+++ b/src/InternPool.zig
@@ -17,6 +17,13 @@ tid_shift_31: if (single_threaded) u0 else std.math.Log2Int(u32),
/// Cached shift amount to put a `tid` in the top bits of a 32-bit value.
tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32),
+/// Dependencies on whether an entire file gets past AstGen.
+/// These are triggered by `@import`, so that:
+/// * if a file initially fails AstGen, triggering a transitive failure, when a future update
+/// causes it to succeed AstGen, the `@import` is re-analyzed, allowing analysis to proceed
+/// * if a file initially succeds AstGen, but a future update causes the file to fail it,
+/// the `@import` is re-analyzed, registering a transitive failure
+file_deps: std.AutoArrayHashMapUnmanaged(FileIndex, DepEntry.Index),
/// Dependencies on the source code hash associated with a ZIR instruction.
/// * For a `declaration`, this is the entire declaration body.
/// * For a `struct_decl`, `union_decl`, etc, this is the source of the fields (but not declarations).
@@ -70,6 +77,7 @@ pub const empty: InternPool = .{
.tid_shift_30 = if (single_threaded) 0 else 31,
.tid_shift_31 = if (single_threaded) 0 else 31,
.tid_shift_32 = if (single_threaded) 0 else 31,
+ .file_deps = .empty,
.src_hash_deps = .empty,
.nav_val_deps = .empty,
.interned_deps = .empty,
@@ -656,6 +664,7 @@ pub const Nav = struct {
};
pub const Dependee = union(enum) {
+ file: FileIndex,
src_hash: TrackedInst.Index,
nav_val: Nav.Index,
interned: Index,
@@ -704,6 +713,7 @@ pub const DependencyIterator = struct {
pub fn dependencyIterator(ip: *const InternPool, dependee: Dependee) DependencyIterator {
const first_entry = switch (dependee) {
+ .file => |x| ip.file_deps.get(x),
.src_hash => |x| ip.src_hash_deps.get(x),
.nav_val => |x| ip.nav_val_deps.get(x),
.interned => |x| ip.interned_deps.get(x),
@@ -740,6 +750,7 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalUnit, depend
const new_index: DepEntry.Index = switch (dependee) {
inline else => |dependee_payload, tag| new_index: {
const gop = try switch (tag) {
+ .file => ip.file_deps,
.src_hash => ip.src_hash_deps,
.nav_val => ip.nav_val_deps,
.interned => ip.interned_deps,
@@ -6268,6 +6279,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
}
pub fn deinit(ip: *InternPool, gpa: Allocator) void {
+ ip.file_deps.deinit(gpa);
ip.src_hash_deps.deinit(gpa);
ip.nav_val_deps.deinit(gpa);
ip.interned_deps.deinit(gpa);