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 {...@@ -3328,7 +3328,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3328 if (comp.zcu) |zcu| zcu_errors: {3328 if (comp.zcu) |zcu| zcu_errors: {
3329 for (zcu.failed_files.keys(), zcu.failed_files.values()) |file, error_msg| {3329 for (zcu.failed_files.keys(), zcu.failed_files.values()) |file, error_msg| {
3330 if (error_msg) |msg| {3330 if (error_msg) |msg| {
3331 try addModuleErrorMsg(zcu, &bundle, msg.*);3331 try addModuleErrorMsg(zcu, &bundle, msg.*, false);
3332 } else {3332 } else {
3333 // Must be ZIR or Zoir errors. Note that this may include AST errors.3333 // Must be ZIR or Zoir errors. Note that this may include AST errors.
3334 _ = try file.getTree(gpa); // Tree must be loaded.3334 _ = try file.getTree(gpa); // Tree must be loaded.
...@@ -3378,6 +3378,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3378,6 +3378,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3378 break :s entries.slice();3378 break :s entries.slice();
3379 };3379 };
3380 defer sorted_failed_analysis.deinit(gpa);3380 defer sorted_failed_analysis.deinit(gpa);
3381 var added_any_analysis_error = false;
3381 for (sorted_failed_analysis.items(.key), sorted_failed_analysis.items(.value)) |anal_unit, error_msg| {3382 for (sorted_failed_analysis.items(.key), sorted_failed_analysis.items(.value)) |anal_unit, error_msg| {
3382 if (comp.incremental) {3383 if (comp.incremental) {
3383 const refs = try zcu.resolveReferences();3384 const refs = try zcu.resolveReferences();
...@@ -3389,7 +3390,9 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3389,7 +3390,9 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3389 zcu.fmtAnalUnit(anal_unit),3390 zcu.fmtAnalUnit(anal_unit),
3390 });3391 });
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
3393 if (zcu.cimport_errors.get(anal_unit)) |errors| {3396 if (zcu.cimport_errors.get(anal_unit)) |errors| {
3394 for (errors.getMessages()) |err_msg_index| {3397 for (errors.getMessages()) |err_msg_index| {
3395 const err_msg = errors.getErrorMessage(err_msg_index);3398 const err_msg = errors.getErrorMessage(err_msg_index);
...@@ -3412,13 +3415,13 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3412,13 +3415,13 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3412 }3415 }
3413 }3416 }
3414 for (zcu.failed_codegen.values()) |error_msg| {3417 for (zcu.failed_codegen.values()) |error_msg| {
3415 try addModuleErrorMsg(zcu, &bundle, error_msg.*);3418 try addModuleErrorMsg(zcu, &bundle, error_msg.*, false);
3416 }3419 }
3417 for (zcu.failed_types.values()) |error_msg| {3420 for (zcu.failed_types.values()) |error_msg| {
3418 try addModuleErrorMsg(zcu, &bundle, error_msg.*);3421 try addModuleErrorMsg(zcu, &bundle, error_msg.*, false);
3419 }3422 }
3420 for (zcu.failed_exports.values()) |value| {3423 for (zcu.failed_exports.values()) |value| {
3421 try addModuleErrorMsg(zcu, &bundle, value.*);3424 try addModuleErrorMsg(zcu, &bundle, value.*, false);
3422 }3425 }
34233426
3424 const actual_error_count = zcu.intern_pool.global_error_set.getNamesFromMainThread().len;3427 const actual_error_count = zcu.intern_pool.global_error_set.getNamesFromMainThread().len;
...@@ -3527,7 +3530,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3527,7 +3530,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3527 // We don't actually include the error here if `!include_compile_log_sources`.3530 // We don't actually include the error here if `!include_compile_log_sources`.
3528 // The sorting above was still necessary, though, to get `log_text` in the right order.3531 // The sorting above was still necessary, though, to get `log_text` in the right order.
3529 if (include_compile_log_sources) {3532 if (include_compile_log_sources) {
3530 try addModuleErrorMsg(zcu, &bundle, messages.items[0]);3533 try addModuleErrorMsg(zcu, &bundle, messages.items[0], false);
3531 }3534 }
35323535
3533 break :compile_log_text try log_text.toOwnedSlice(gpa);3536 break :compile_log_text try log_text.toOwnedSlice(gpa);
...@@ -3631,10 +3634,14 @@ pub const ErrorNoteHashContext = struct {...@@ -3631,10 +3634,14 @@ pub const ErrorNoteHashContext = struct {
3631 }3634 }
3632};3635};
36333636
3637const default_reference_trace_len = 2;
3634pub fn addModuleErrorMsg(3638pub fn addModuleErrorMsg(
3635 zcu: *Zcu,3639 zcu: *Zcu,
3636 eb: *ErrorBundle.Wip,3640 eb: *ErrorBundle.Wip,
3637 module_err_msg: Zcu.ErrorMsg,3641 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,
3638) !void {3645) !void {
3639 const gpa = eb.gpa;3646 const gpa = eb.gpa;
3640 const ip = &zcu.intern_pool;3647 const ip = &zcu.intern_pool;
...@@ -3657,14 +3664,18 @@ pub fn addModuleErrorMsg(...@@ -3657,14 +3664,18 @@ pub fn addModuleErrorMsg(
3657 var ref_traces: std.ArrayListUnmanaged(ErrorBundle.ReferenceTrace) = .empty;3664 var ref_traces: std.ArrayListUnmanaged(ErrorBundle.ReferenceTrace) = .empty;
3658 defer ref_traces.deinit(gpa);3665 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
3661 const all_references = try zcu.resolveReferences();3674 const all_references = try zcu.resolveReferences();
36623675
3663 var seen: std.AutoHashMapUnmanaged(InternPool.AnalUnit, void) = .empty;3676 var seen: std.AutoHashMapUnmanaged(InternPool.AnalUnit, void) = .empty;
3664 defer seen.deinit(gpa);3677 defer seen.deinit(gpa);
36653678
3666 const max_references = zcu.comp.reference_trace orelse Sema.default_reference_trace_len;
3667
3668 var referenced_by = rt_root;3679 var referenced_by = rt_root;
3669 while (all_references.get(referenced_by)) |maybe_ref| {3680 while (all_references.get(referenced_by)) |maybe_ref| {
3670 const ref = maybe_ref orelse break;3681 const ref = maybe_ref orelse break;
src/Sema.zig+2-6
...@@ -191,7 +191,6 @@ const LowerZon = @import("Sema/LowerZon.zig");...@@ -191,7 +191,6 @@ const LowerZon = @import("Sema/LowerZon.zig");
191const arith = @import("Sema/arith.zig");191const arith = @import("Sema/arith.zig");
192192
193pub const default_branch_quota = 1000;193pub const default_branch_quota = 1000;
194pub const default_reference_trace_len = 2;
195194
196pub const InferredErrorSet = struct {195pub const InferredErrorSet = struct {
197 /// The function body from which this error set originates.196 /// The function body from which this error set originates.
...@@ -2580,7 +2579,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg...@@ -2580,7 +2579,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg
2580 if (build_options.enable_debug_extensions and zcu.comp.debug_compile_errors) {2579 if (build_options.enable_debug_extensions and zcu.comp.debug_compile_errors) {
2581 var wip_errors: std.zig.ErrorBundle.Wip = undefined;2580 var wip_errors: std.zig.ErrorBundle.Wip = undefined;
2582 wip_errors.init(gpa) catch @panic("out of memory");2581 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");
2584 std.debug.print("compile error during Sema:\n", .{});2583 std.debug.print("compile error during Sema:\n", .{});
2585 var error_bundle = wip_errors.toOwnedBundle("") catch @panic("out of memory");2584 var error_bundle = wip_errors.toOwnedBundle("") catch @panic("out of memory");
2586 error_bundle.renderToStdErr(.{ .ttyconf = .no_color });2585 error_bundle.renderToStdErr(.{ .ttyconf = .no_color });
...@@ -2600,10 +2599,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg...@@ -2600,10 +2599,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg
2600 }2599 }
2601 }2600 }
26022601
2603 const use_ref_trace = if (zcu.comp.reference_trace) |n| n > 0 else zcu.failed_analysis.count() == 0;2602 err_msg.reference_trace_root = sema.owner.toOptional();
2604 if (use_ref_trace) {
2605 err_msg.reference_trace_root = sema.owner.toOptional();
2606 }
26072603
2608 const gop = try zcu.failed_analysis.getOrPut(gpa, sema.owner);2604 const gop = try zcu.failed_analysis.getOrPut(gpa, sema.owner);
2609 if (gop.found_existing) {2605 if (gop.found_existing) {