authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-03-30 22:59:25+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-05-16 11:55:35+01:00
log70040778fbde5d7fcbbfc26dbabc700024c538d5
tree171a2b244a979e0943305f1460e466c6a1d2123b
parentcc1475c91da6005d72192b426e8b9ec6db7a3f74
signaturelock-open Commit is signed but in an unrecognized format.

Compilation: fix reference trace behavior without `-freference-trace`

When `-freference-trace` is not passed, we want to show exactly one reference trace. Previously, we set the reference trace root in `Sema` iff there were no other failed analyses. However, this results in an arbitrary error being the one with the reference trace after error sorting. It is also incompatible with incremental compilation, where some errors might be unreferenced. Instead, set the field on all analysis errors, and decide in `Compilation.getAllErrorsAlloc` which reference trace[s] to actually show.

2 files changed, 22 insertions(+), 15 deletions(-)

src/Compilation.zig+20-9
......@@ -3328,7 +3328,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
33283328 if (comp.zcu) |zcu| zcu_errors: {
33293329 for (zcu.failed_files.keys(), zcu.failed_files.values()) |file, error_msg| {
33303330 if (error_msg) |msg| {
3331 try addModuleErrorMsg(zcu, &bundle, msg.*);
3331 try addModuleErrorMsg(zcu, &bundle, msg.*, false);
33323332 } else {
33333333 // Must be ZIR or Zoir errors. Note that this may include AST errors.
33343334 _ = try file.getTree(gpa); // Tree must be loaded.
......@@ -3378,6 +3378,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
33783378 break :s entries.slice();
33793379 };
33803380 defer sorted_failed_analysis.deinit(gpa);
3381 var added_any_analysis_error = false;
33813382 for (sorted_failed_analysis.items(.key), sorted_failed_analysis.items(.value)) |anal_unit, error_msg| {
33823383 if (comp.incremental) {
33833384 const refs = try zcu.resolveReferences();
......@@ -3389,7 +3390,9 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
33893390 zcu.fmtAnalUnit(anal_unit),
33903391 });
33913392
3392 try addModuleErrorMsg(zcu, &bundle, error_msg.*);
3393 try addModuleErrorMsg(zcu, &bundle, error_msg.*, added_any_analysis_error);
3394 added_any_analysis_error = true;
3395
33933396 if (zcu.cimport_errors.get(anal_unit)) |errors| {
33943397 for (errors.getMessages()) |err_msg_index| {
33953398 const err_msg = errors.getErrorMessage(err_msg_index);
......@@ -3412,13 +3415,13 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
34123415 }
34133416 }
34143417 for (zcu.failed_codegen.values()) |error_msg| {
3415 try addModuleErrorMsg(zcu, &bundle, error_msg.*);
3418 try addModuleErrorMsg(zcu, &bundle, error_msg.*, false);
34163419 }
34173420 for (zcu.failed_types.values()) |error_msg| {
3418 try addModuleErrorMsg(zcu, &bundle, error_msg.*);
3421 try addModuleErrorMsg(zcu, &bundle, error_msg.*, false);
34193422 }
34203423 for (zcu.failed_exports.values()) |value| {
3421 try addModuleErrorMsg(zcu, &bundle, value.*);
3424 try addModuleErrorMsg(zcu, &bundle, value.*, false);
34223425 }
34233426
34243427 const actual_error_count = zcu.intern_pool.global_error_set.getNamesFromMainThread().len;
......@@ -3527,7 +3530,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
35273530 // We don't actually include the error here if `!include_compile_log_sources`.
35283531 // The sorting above was still necessary, though, to get `log_text` in the right order.
35293532 if (include_compile_log_sources) {
3530 try addModuleErrorMsg(zcu, &bundle, messages.items[0]);
3533 try addModuleErrorMsg(zcu, &bundle, messages.items[0], false);
35313534 }
35323535
35333536 break :compile_log_text try log_text.toOwnedSlice(gpa);
......@@ -3631,10 +3634,14 @@ pub const ErrorNoteHashContext = struct {
36313634 }
36323635};
36333636
3637const default_reference_trace_len = 2;
36343638pub fn addModuleErrorMsg(
36353639 zcu: *Zcu,
36363640 eb: *ErrorBundle.Wip,
36373641 module_err_msg: Zcu.ErrorMsg,
3642 /// If `-freference-trace` is not specified, we only want to show the one reference trace.
3643 /// So, this is whether we have already emitted an error with a reference trace.
3644 already_added_error: bool,
36383645) !void {
36393646 const gpa = eb.gpa;
36403647 const ip = &zcu.intern_pool;
......@@ -3657,14 +3664,18 @@ pub fn addModuleErrorMsg(
36573664 var ref_traces: std.ArrayListUnmanaged(ErrorBundle.ReferenceTrace) = .empty;
36583665 defer ref_traces.deinit(gpa);
36593666
3660 if (module_err_msg.reference_trace_root.unwrap()) |rt_root| {
3667 rt: {
3668 const rt_root = module_err_msg.reference_trace_root.unwrap() orelse break :rt;
3669 const max_references = zcu.comp.reference_trace orelse refs: {
3670 if (already_added_error) break :rt;
3671 break :refs default_reference_trace_len;
3672 };
3673
36613674 const all_references = try zcu.resolveReferences();
36623675
36633676 var seen: std.AutoHashMapUnmanaged(InternPool.AnalUnit, void) = .empty;
36643677 defer seen.deinit(gpa);
36653678
3666 const max_references = zcu.comp.reference_trace orelse Sema.default_reference_trace_len;
3667
36683679 var referenced_by = rt_root;
36693680 while (all_references.get(referenced_by)) |maybe_ref| {
36703681 const ref = maybe_ref orelse break;
src/Sema.zig+2-6
......@@ -191,7 +191,6 @@ const LowerZon = @import("Sema/LowerZon.zig");
191191const arith = @import("Sema/arith.zig");
192192
193193pub const default_branch_quota = 1000;
194pub const default_reference_trace_len = 2;
195194
196195pub const InferredErrorSet = struct {
197196 /// The function body from which this error set originates.
......@@ -2580,7 +2579,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg
25802579 if (build_options.enable_debug_extensions and zcu.comp.debug_compile_errors) {
25812580 var wip_errors: std.zig.ErrorBundle.Wip = undefined;
25822581 wip_errors.init(gpa) catch @panic("out of memory");
2583 Compilation.addModuleErrorMsg(zcu, &wip_errors, err_msg.*) catch @panic("out of memory");
2582 Compilation.addModuleErrorMsg(zcu, &wip_errors, err_msg.*, false) catch @panic("out of memory");
25842583 std.debug.print("compile error during Sema:\n", .{});
25852584 var error_bundle = wip_errors.toOwnedBundle("") catch @panic("out of memory");
25862585 error_bundle.renderToStdErr(.{ .ttyconf = .no_color });
......@@ -2600,10 +2599,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg
26002599 }
26012600 }
26022601
2603 const use_ref_trace = if (zcu.comp.reference_trace) |n| n > 0 else zcu.failed_analysis.count() == 0;
2604 if (use_ref_trace) {
2605 err_msg.reference_trace_root = sema.owner.toOptional();
2606 }
2602 err_msg.reference_trace_root = sema.owner.toOptional();
26072603
26082604 const gop = try zcu.failed_analysis.getOrPut(gpa, sema.owner);
26092605 if (gop.found_existing) {