diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index d062f68ec946d85481b9a29c5c2eb5de5cf6e5ca..4092f27b8b7ca16a56b412805779584b801561f9 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -3262,9 +3262,7 @@ fn analyzeFuncBodyInner( 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_analysis.zir_index }); - try sema.declareDependency(.{ .nav_val = func.owner_nav }); // Make sure that the declaration `Nav` still refers to this function (or its generic owner). // This will not be the case if the incremental update has changed a function type or turned a @@ -3275,6 +3273,7 @@ fn analyzeFuncBodyInner( // If we *are* still owned by the right NAV, this analysis updates `zir_body_inst` if necessary. if (func.generic_owner == .none) { + try sema.declareDependency(.{ .nav_val = func.owner_nav }); pt.ensureNavValUpToDate(func.owner_nav, reason) catch |err| switch (err) { error.AnalysisFail => return sema.failTransitive(.{ .failed_unit = .wrap(.{ .nav_val = func.owner_nav }) }), else => |e| return e, @@ -3284,6 +3283,7 @@ fn analyzeFuncBodyInner( } } else { const go_nav = zcu.funcInfo(func.generic_owner).owner_nav; + try sema.declareDependency(.{ .nav_val = go_nav }); pt.ensureNavValUpToDate(go_nav, reason) catch |err| switch (err) { error.AnalysisFail => return sema.failTransitive(.{ .failed_unit = .wrap(.{ .nav_val = go_nav }) }), else => |e| return e, diff --git a/test/incremental/temporary_analysis_error_in_generic_signature b/test/incremental/temporary_analysis_error_in_generic_signature new file mode 100644 index 0000000000000000000000000000000000000000..d8db72050b3af1164a312e1e7a1ed1f89bfc3dae --- /dev/null +++ b/test/incremental/temporary_analysis_error_in_generic_signature @@ -0,0 +1,46 @@ +#update=initial version +#file=main.zig +//! The original repro here depends on re-analysis order, which depends on +//! declaration order, so this exact declaration order must be used. +const Foo = struct { x: u8 }; +pub fn main(init: std.process.Init) !void { + const c = bar('Z').x; + try std.Io.File.stdout().writeStreamingAll(init.io, &.{ c, '\n' }); +} +fn bar(comptime x: u8) @This().Foo { + return .{ .x = x }; +} +const std = @import("std"); +#expect_stdout="Z\n" + +#update=change generic signature to use non-existent member +#file=main.zig +//! The original repro here depends on re-analysis order, which depends on +//! declaration order, so this exact declaration order must be used. +const Foo = struct { x: u8 }; +pub fn main(init: std.process.Init) !void { + const c = bar('Z').x; + try std.Io.File.stdout().writeStreamingAll(init.io, &.{ c, '\n' }); +} +fn bar(comptime x: u8) @This().FooAlias { + return .{ .x = x }; +} +const std = @import("std"); +#expect_error=main.zig:8:31: error: root source file struct 'main' has no member named 'FooAlias' +#expect_error=main.zig:1:1: note: struct declared here + +#update=add that member, fixing the error +#file=main.zig +//! The original repro here depends on re-analysis order, which depends on +//! declaration order, so this exact declaration order must be used. +const Foo = struct { x: u8 }; +const FooAlias = Foo; +pub fn main(init: std.process.Init) !void { + const c = bar('Z').x; + try std.Io.File.stdout().writeStreamingAll(init.io, &.{ c, '\n' }); +} +fn bar(comptime x: u8) @This().FooAlias { + return .{ .x = x }; +} +const std = @import("std"); +#expect_stdout="Z\n"