authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-01 21:49:02+00:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-01-01 21:49:02+00:00
log0585ed0641ca1d57c3138b641252dc181e0cad3d
tree0523207bee95cd60c394de781c03c851e8c538ea
parent5333d2443a80a82b34940be68e4ca8d1129b7ab7
parentf0d5e0df4d95c06287e0fe3fe48b69daf5306c8f
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #22379 from mlugg/incremental-fixes

incremental: bugfixes

4 files changed, 112 insertions(+), 23 deletions(-)

lib/std/zig/Zir.zig+29-8
......@@ -4481,11 +4481,18 @@ fn findTrackableInner(
44814481 .func,
44824482 .func_inferred,
44834483 => {
4484 const inst_data = datas[@intFromEnum(inst)].pl_node;
4485 const extra = zir.extraData(Inst.Func, inst_data.payload_index);
4486
4487 if (extra.data.body_len == 0) {
4488 // This is just a prototype. No need to track.
4489 assert(extra.data.ret_body_len < 2);
4490 return;
4491 }
4492
44844493 assert(contents.func_decl == null);
44854494 contents.func_decl = inst;
44864495
4487 const inst_data = datas[@intFromEnum(inst)].pl_node;
4488 const extra = zir.extraData(Inst.Func, inst_data.payload_index);
44894496 var extra_index: usize = extra.end;
44904497 switch (extra.data.ret_body_len) {
44914498 0 => {},
......@@ -4500,11 +4507,19 @@ fn findTrackableInner(
45004507 return zir.findTrackableBody(gpa, contents, defers, body);
45014508 },
45024509 .func_fancy => {
4510 const inst_data = datas[@intFromEnum(inst)].pl_node;
4511 const extra = zir.extraData(Inst.FuncFancy, inst_data.payload_index);
4512
4513 if (extra.data.body_len == 0) {
4514 // This is just a prototype. No need to track.
4515 assert(!extra.data.bits.has_cc_body);
4516 assert(!extra.data.bits.has_ret_ty_body);
4517 return;
4518 }
4519
45034520 assert(contents.func_decl == null);
45044521 contents.func_decl = inst;
45054522
4506 const inst_data = datas[@intFromEnum(inst)].pl_node;
4507 const extra = zir.extraData(Inst.FuncFancy, inst_data.payload_index);
45084523 var extra_index: usize = extra.end;
45094524
45104525 if (extra.data.bits.has_cc_body) {
......@@ -5026,10 +5041,16 @@ pub fn assertTrackable(zir: Zir, inst_idx: Zir.Inst.Index) void {
50265041 .struct_init_ref,
50275042 .struct_init_anon,
50285043 => {}, // tracked in order, as the owner instructions of anonymous struct types
5029 .func,
5030 .func_inferred,
5031 .func_fancy,
5032 => {}, // tracked in order, as the owner instructions of function bodies
5044 .func, .func_inferred => {
5045 // These are tracked provided they are actual function declarations, not just bodies.
5046 const extra = zir.extraData(Inst.Func, inst.data.pl_node.payload_index);
5047 assert(extra.data.body_len != 0);
5048 },
5049 .func_fancy => {
5050 // These are tracked provided they are actual function declarations, not just bodies.
5051 const extra = zir.extraData(Inst.FuncFancy, inst.data.pl_node.payload_index);
5052 assert(extra.data.body_len != 0);
5053 },
50335054 .declaration => {}, // tracked by correlating names in the namespace of the parent container
50345055 .extended => switch (inst.data.extended.opcode) {
50355056 .struct_decl,
src/Compilation.zig+25-9
......@@ -3102,9 +3102,10 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
31023102 for (zcu.failed_embed_files.values()) |error_msg| {
31033103 try addModuleErrorMsg(zcu, &bundle, error_msg.*);
31043104 }
3105 {
3105 var sorted_failed_analysis: std.AutoArrayHashMapUnmanaged(InternPool.AnalUnit, *Zcu.ErrorMsg).DataList.Slice = s: {
31063106 const SortOrder = struct {
31073107 zcu: *Zcu,
3108 errors: []const *Zcu.ErrorMsg,
31083109 err: *?Error,
31093110
31103111 const Error = @typeInfo(
......@@ -3113,12 +3114,11 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
31133114
31143115 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {
31153116 if (ctx.err.*) |_| return lhs_index < rhs_index;
3116 const errors = ctx.zcu.failed_analysis.values();
3117 const lhs_src_loc = errors[lhs_index].src_loc.upgradeOrLost(ctx.zcu) orelse {
3117 const lhs_src_loc = ctx.errors[lhs_index].src_loc.upgradeOrLost(ctx.zcu) orelse {
31183118 // LHS source location lost, so should never be referenced. Just sort it to the end.
31193119 return false;
31203120 };
3121 const rhs_src_loc = errors[rhs_index].src_loc.upgradeOrLost(ctx.zcu) orelse {
3121 const rhs_src_loc = ctx.errors[rhs_index].src_loc.upgradeOrLost(ctx.zcu) orelse {
31223122 // RHS source location lost, so should never be referenced. Just sort it to the end.
31233123 return true;
31243124 };
......@@ -3135,13 +3135,24 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
31353135 }).main;
31363136 }
31373137 };
3138
3139 // We can't directly sort `zcu.failed_analysis.entries`, because that would leave the map
3140 // in an invalid state, and we need it intact for future incremental updates. The amount
3141 // of data here is only as large as the number of analysis errors, so just dupe it all.
3142 var entries = try zcu.failed_analysis.entries.clone(gpa);
3143 errdefer entries.deinit(gpa);
3144
31383145 var err: ?SortOrder.Error = null;
3139 // This leaves `zcu.failed_analysis` an invalid state, but we do not
3140 // need lookups anymore anyway.
3141 zcu.failed_analysis.entries.sort(SortOrder{ .zcu = zcu, .err = &err });
3146 entries.sort(SortOrder{
3147 .zcu = zcu,
3148 .errors = entries.items(.value),
3149 .err = &err,
3150 });
31423151 if (err) |e| return e;
3143 }
3144 for (zcu.failed_analysis.keys(), zcu.failed_analysis.values()) |anal_unit, error_msg| {
3152 break :s entries.slice();
3153 };
3154 defer sorted_failed_analysis.deinit(gpa);
3155 for (sorted_failed_analysis.items(.key), sorted_failed_analysis.items(.value)) |anal_unit, error_msg| {
31453156 if (comp.incremental) {
31463157 const refs = try zcu.resolveReferences();
31473158 if (!refs.contains(anal_unit)) continue;
......@@ -3158,6 +3169,11 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
31583169 // We'll try again once parsing succeeds.
31593170 if (!zcu.fileByIndex(file_index).okToReportErrors()) continue;
31603171
3172 std.log.scoped(.zcu).debug("analysis error '{s}' reported from unit '{}'", .{
3173 error_msg.msg,
3174 zcu.fmtAnalUnit(anal_unit),
3175 });
3176
31613177 try addModuleErrorMsg(zcu, &bundle, error_msg.*);
31623178 if (zcu.cimport_errors.get(anal_unit)) |errors| {
31633179 for (errors.getMessages()) |err_msg_index| {
src/Zcu.zig+6-6
......@@ -3590,17 +3590,17 @@ fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, comptime fmt: []co
35903590 const cu = ip.getComptimeUnit(cu_id);
35913591 if (cu.zir_index.resolveFull(ip)) |resolved| {
35923592 const file_path = zcu.fileByIndex(resolved.file).sub_file_path;
3593 return writer.print("comptime(inst=('{s}', %{}))", .{ file_path, @intFromEnum(resolved.inst) });
3593 return writer.print("comptime(inst=('{s}', %{}) [{}])", .{ file_path, @intFromEnum(resolved.inst), @intFromEnum(cu_id) });
35943594 } else {
3595 return writer.writeAll("comptime(inst=<list>)");
3595 return writer.print("comptime(inst=<lost> [{}])", .{@intFromEnum(cu_id)});
35963596 }
35973597 },
3598 .nav_val => |nav| return writer.print("nav_val('{}')", .{ip.getNav(nav).fqn.fmt(ip)}),
3599 .nav_ty => |nav| return writer.print("nav_ty('{}')", .{ip.getNav(nav).fqn.fmt(ip)}),
3600 .type => |ty| return writer.print("ty('{}')", .{Type.fromInterned(ty).containerTypeName(ip).fmt(ip)}),
3598 .nav_val => |nav| return writer.print("nav_val('{}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) }),
3599 .nav_ty => |nav| return writer.print("nav_ty('{}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) }),
3600 .type => |ty| return writer.print("ty('{}' [{}])", .{ Type.fromInterned(ty).containerTypeName(ip).fmt(ip), @intFromEnum(ty) }),
36013601 .func => |func| {
36023602 const nav = zcu.funcInfo(func).owner_nav;
3603 return writer.print("func('{}')", .{ip.getNav(nav).fqn.fmt(ip)});
3603 return writer.print("func('{}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(func) });
36043604 },
36053605 }
36063606}
test/incremental/fix_many_errors created+52
......@@ -0,0 +1,52 @@
1#target=x86_64-linux-selfhosted
2#target=x86_64-linux-cbe
3#target=x86_64-windows-cbe
4#update=initial version
5#file=main.zig
6pub fn main() !void {}
7comptime { @compileError("c0"); }
8comptime { @compileError("c1"); }
9comptime { @compileError("c2"); }
10comptime { @compileError("c3"); }
11comptime { @compileError("c4"); }
12comptime { @compileError("c5"); }
13comptime { @compileError("c6"); }
14comptime { @compileError("c7"); }
15comptime { @compileError("c8"); }
16comptime { @compileError("c9"); }
17export fn f0() void { @compileError("f0"); }
18export fn f1() void { @compileError("f1"); }
19export fn f2() void { @compileError("f2"); }
20export fn f3() void { @compileError("f3"); }
21export fn f4() void { @compileError("f4"); }
22export fn f5() void { @compileError("f5"); }
23export fn f6() void { @compileError("f6"); }
24export fn f7() void { @compileError("f7"); }
25export fn f8() void { @compileError("f8"); }
26export fn f9() void { @compileError("f9"); }
27#expect_error=ignored
28#update=fix all the errors
29#file=main.zig
30pub fn main() !void {}
31comptime {}
32comptime {}
33comptime {}
34comptime {}
35comptime {}
36comptime {}
37comptime {}
38comptime {}
39comptime {}
40comptime {}
41export fn f0() void {}
42export fn f1() void {}
43export fn f2() void {}
44export fn f3() void {}
45export fn f4() void {}
46export fn f5() void {}
47export fn f6() void {}
48export fn f7() void {}
49export fn f8() void {}
50export fn f9() void {}
51const std = @import("std");
52#expect_stdout=""