From 31daea74d23be813737892a166cc16ade1272a1a Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Fri, 9 Sep 2022 18:55:58 +0300 Subject: [PATCH] stage2: implement referenced by trace for error messages Closes #7668 Closes #12141 --- lib/build_runner.zig | 12 +++ lib/std/build.zig | 5 ++ src/Compilation.zig | 62 +++++++++++++ src/Module.zig | 20 +++++ src/Sema.zig | 87 +++++++++++++------ src/main.zig | 49 ++++++++--- src/test.zig | 1 + .../top_level_decl_dependency_loop.zig | 1 - 8 files changed, 197 insertions(+), 40 deletions(-) diff --git a/lib/build_runner.zig b/lib/build_runner.zig index 523723ddf2..f47822f0b7 100644 --- a/lib/build_runner.zig +++ b/lib/build_runner.zig @@ -185,6 +185,16 @@ pub fn main() !void { builder.use_stage1 = true; } else if (mem.eql(u8, arg, "-fno-stage1")) { builder.use_stage1 = false; + } else if (mem.eql(u8, arg, "-freference-trace")) { + builder.reference_trace = 256; + } else if (mem.startsWith(u8, arg, "-freference-trace=")) { + const num = arg["-freference-trace=".len..]; + builder.reference_trace = std.fmt.parseUnsigned(u32, num, 10) catch |err| { + std.debug.print("unable to parse reference_trace count '{s}': {s}", .{ num, @errorName(err) }); + process.exit(1); + }; + } else if (mem.eql(u8, arg, "-fno-reference-trace")) { + builder.reference_trace = null; } else if (mem.eql(u8, arg, "--")) { builder.args = argsRest(args, arg_idx); break; @@ -308,6 +318,8 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: anytype) !void \\Advanced Options: \\ -fstage1 Force using bootstrap compiler as the codegen backend \\ -fno-stage1 Prevent using bootstrap compiler as the codegen backend + \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error + \\ -fno-reference-trace Disable reference trace \\ --build-file [file] Override path to build.zig \\ --cache-dir [path] Override path to local Zig cache directory \\ --global-cache-dir [path] Override path to global Zig cache directory diff --git a/lib/std/build.zig b/lib/std/build.zig index f11dba717d..3a6e6dfb3b 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -45,6 +45,7 @@ pub const Builder = struct { /// The purpose of executing the command is for a human to read compile errors from the terminal prominent_compile_errors: bool, color: enum { auto, on, off } = .auto, + reference_trace: ?u32 = null, use_stage1: ?bool = null, invalid_user_input: bool, zig_exe: []const u8, @@ -2475,6 +2476,10 @@ pub const LibExeObjStep = struct { try zig_args.append(@tagName(builder.color)); } + if (builder.reference_trace) |some| { + try zig_args.append(try std.fmt.allocPrint(builder.allocator, "-freference-trace={d}", .{some})); + } + if (self.use_stage1) |stage1| { if (stage1) { try zig_args.append("-fstage1"); diff --git a/src/Compilation.zig b/src/Compilation.zig index 04de522fa5..f0d100cb9a 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -154,6 +154,10 @@ owned_link_dir: ?std.fs.Dir, /// Don't use this for anything other than stage1 compatibility. color: Color = .auto, +/// How many lines of reference trace should be included per compile error. +/// Null means only show snippet on first error. +reference_trace: ?u32 = null, + libcxx_abi_version: libcxx.AbiVersion = libcxx.AbiVersion.default, /// This mutex guards all `Compilation` mutable state. @@ -348,6 +352,7 @@ pub const AllErrors = struct { /// Does not include the trailing newline. source_line: ?[]const u8, notes: []Message = &.{}, + reference_trace: []Message = &.{}, /// Splits the error message up into lines to properly indent them /// to allow for long, good-looking error messages. @@ -447,6 +452,34 @@ pub const AllErrors = struct { for (src.notes) |note| { try note.renderToWriter(ttyconf, stderr, "note", .Cyan, indent); } + if (src.reference_trace.len != 0) { + ttyconf.setColor(stderr, .Reset); + ttyconf.setColor(stderr, .Dim); + try stderr.print("referenced by:\n", .{}); + for (src.reference_trace) |reference| { + switch (reference) { + .src => |ref_src| try stderr.print(" {s}: {s}:{d}:{d}\n", .{ + ref_src.msg, + ref_src.src_path, + ref_src.line + 1, + ref_src.column + 1, + }), + .plain => |plain| if (plain.count != 0) { + try stderr.print( + " {d} reference(s) hidden; use '-freference-trace={d}' to see all references\n", + .{ plain.count, plain.count + src.reference_trace.len - 1 }, + ); + } else { + try stderr.print( + " remaining reference traces hidden; use '-freference-trace' to see all reference traces\n", + .{}, + ); + }, + } + } + try stderr.writeByte('\n'); + ttyconf.setColor(stderr, .Reset); + } }, .plain => |plain| { ttyconf.setColor(stderr, color); @@ -572,6 +605,32 @@ pub const AllErrors = struct { }); return; } + + const reference_trace = try allocator.alloc(Message, module_err_msg.reference_trace.len); + for (reference_trace) |*reference, i| { + const module_reference = module_err_msg.reference_trace[i]; + if (module_reference.hidden != 0) { + reference.* = .{ .plain = .{ .msg = undefined, .count = module_reference.hidden } }; + break; + } else if (module_reference.decl == null) { + reference.* = .{ .plain = .{ .msg = undefined, .count = 0 } }; + break; + } + const source = try module_reference.src_loc.file_scope.getSource(module.gpa); + const span = try module_reference.src_loc.span(module.gpa); + const loc = std.zig.findLineColumn(source.bytes, span.main); + const file_path = try module_reference.src_loc.file_scope.fullPath(allocator); + reference.* = .{ + .src = .{ + .src_path = file_path, + .msg = try allocator.dupe(u8, std.mem.sliceTo(module_reference.decl.?, 0)), + .span = span, + .line = @intCast(u32, loc.line), + .column = @intCast(u32, loc.column), + .source_line = null, + }, + }; + } const file_path = try module_err_msg.src_loc.file_scope.fullPath(allocator); try errors.append(.{ .src = .{ @@ -581,6 +640,7 @@ pub const AllErrors = struct { .line = @intCast(u32, err_loc.line), .column = @intCast(u32, err_loc.column), .notes = notes_buf[0..note_i], + .reference_trace = reference_trace, .source_line = try allocator.dupe(u8, err_loc.source_line), }, }); @@ -929,6 +989,7 @@ pub const InitOptions = struct { clang_preprocessor_mode: ClangPreprocessorMode = .no, /// This is for stage1 and should be deleted upon completion of self-hosting. color: Color = .auto, + reference_trace: ?u32 = null, test_filter: ?[]const u8 = null, test_name_prefix: ?[]const u8 = null, subsystem: ?std.Target.SubSystem = null, @@ -1838,6 +1899,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { .disable_c_depfile = options.disable_c_depfile, .owned_link_dir = owned_link_dir, .color = options.color, + .reference_trace = options.reference_trace, .time_report = options.time_report, .stack_report = options.stack_report, .unwind_tables = unwind_tables, diff --git a/src/Module.zig b/src/Module.zig index ea89225537..e756cc3dfd 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -166,6 +166,11 @@ decls_free_list: std.ArrayListUnmanaged(Decl.Index) = .{}, global_assembly: std.AutoHashMapUnmanaged(Decl.Index, []u8) = .{}, +reference_table: std.AutoHashMapUnmanaged(Decl.Index, struct { + referencer: Decl.Index, + src: LazySrcLoc, +}) = .{}, + pub const StringLiteralContext = struct { bytes: *std.ArrayListUnmanaged(u8), @@ -2084,6 +2089,13 @@ pub const ErrorMsg = struct { src_loc: SrcLoc, msg: []const u8, notes: []ErrorMsg = &.{}, + reference_trace: []Trace = &.{}, + + pub const Trace = struct { + decl: ?[*:0]const u8, + src_loc: SrcLoc, + hidden: u32 = 0, + }; pub fn create( gpa: Allocator, @@ -2122,8 +2134,15 @@ pub const ErrorMsg = struct { } gpa.free(err_msg.notes); gpa.free(err_msg.msg); + gpa.free(err_msg.reference_trace); err_msg.* = undefined; } + + pub fn clearTrace(err_msg: *ErrorMsg, gpa: Allocator) void { + if (err_msg.reference_trace.len == 0) return; + gpa.free(err_msg.reference_trace); + err_msg.reference_trace = &.{}; + } }; /// Canonical reference to a position within a source file. @@ -3411,6 +3430,7 @@ pub fn deinit(mod: *Module) void { mod.decls_free_list.deinit(gpa); mod.allocated_decls.deinit(gpa); mod.global_assembly.deinit(gpa); + mod.reference_table.deinit(gpa); mod.string_literal_table.deinit(gpa); mod.string_literal_bytes.deinit(gpa); diff --git a/src/Sema.zig b/src/Sema.zig index bcac427caf..2395300279 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -111,6 +111,7 @@ const crash_report = @import("crash_report.zig"); const build_options = @import("build_options"); pub const default_branch_quota = 1000; +pub const default_reference_trace_len = 2; pub const InstMap = std.AutoHashMapUnmanaged(Zir.Inst.Index, Air.Inst.Ref); @@ -1958,13 +1959,53 @@ fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError { } const mod = sema.mod; - { + ref: { errdefer err_msg.destroy(mod.gpa); if (err_msg.src_loc.lazy == .unneeded) { return error.NeededSourceLocation; } try mod.failed_decls.ensureUnusedCapacity(mod.gpa, 1); try mod.failed_files.ensureUnusedCapacity(mod.gpa, 1); + + const max_references = blk: { + if (sema.mod.comp.reference_trace) |num| break :blk num; + // Do not add multiple traces without explicit request. + if (sema.mod.failed_decls.count() != 0) break :ref; + break :blk default_reference_trace_len; + }; + + var referenced_by = if (sema.func) |some| some.owner_decl else sema.owner_decl_index; + var reference_stack = std.ArrayList(Module.ErrorMsg.Trace).init(sema.gpa); + defer reference_stack.deinit(); + + // Avoid infinite loops. + var seen = std.AutoHashMap(Module.Decl.Index, void).init(sema.gpa); + defer seen.deinit(); + + var cur_reference_trace: u32 = 0; + while (sema.mod.reference_table.get(referenced_by)) |ref| : (cur_reference_trace += 1) { + const gop = try seen.getOrPut(ref.referencer); + if (gop.found_existing) break; + if (cur_reference_trace < max_references) { + const decl = sema.mod.declPtr(ref.referencer); + try reference_stack.append(.{ .decl = decl.name, .src_loc = ref.src.toSrcLoc(decl) }); + } + referenced_by = ref.referencer; + } + if (sema.mod.comp.reference_trace == null and cur_reference_trace > 0) { + try reference_stack.append(.{ + .decl = null, + .src_loc = undefined, + .hidden = 0, + }); + } else if (cur_reference_trace > max_references) { + try reference_stack.append(.{ + .decl = undefined, + .src_loc = undefined, + .hidden = cur_reference_trace - max_references, + }); + } + err_msg.reference_trace = reference_stack.toOwnedSlice(); } if (sema.owner_func) |func| { func.state = .sema_failure; @@ -5366,14 +5407,8 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air const src = inst_data.src(); const decl_name = inst_data.get(sema.code); const decl_index = try sema.lookupIdentifier(block, src, decl_name); - return sema.analyzeDeclRef(decl_index) catch |err| switch (err) { - error.AnalysisFail => { - const msg = sema.err orelse return err; - try sema.errNote(block, src, msg, "referenced here", .{}); - return err; - }, - else => return err, - }; + try sema.addReferencedBy(block, src, decl_index); + return sema.analyzeDeclRef(decl_index); } fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -6107,6 +6142,7 @@ fn analyzeCall( error.AnalysisFail => { const err_msg = sema.err orelse return err; try sema.errNote(block, call_src, err_msg, "called from here", .{}); + err_msg.clearTrace(sema.gpa); return err; }, else => |e| return e, @@ -21741,14 +21777,8 @@ fn namespaceLookupRef( decl_name: []const u8, ) CompileError!?Air.Inst.Ref { const decl = (try sema.namespaceLookup(block, src, namespace, decl_name)) orelse return null; - return sema.analyzeDeclRef(decl) catch |err| switch (err) { - error.AnalysisFail => { - const msg = sema.err orelse return err; - try sema.errNote(block, src, msg, "referenced here", .{}); - return err; - }, - else => return err, - }; + try sema.addReferencedBy(block, src, decl); + return try sema.analyzeDeclRef(decl); } fn namespaceLookupVal( @@ -26001,14 +26031,8 @@ fn analyzeDeclVal( if (sema.decl_val_table.get(decl_index)) |result| { return result; } - const decl_ref = sema.analyzeDeclRef(decl_index) catch |err| switch (err) { - error.AnalysisFail => { - const msg = sema.err orelse return err; - try sema.errNote(block, src, msg, "referenced here", .{}); - return err; - }, - else => return err, - }; + try sema.addReferencedBy(block, src, decl_index); + const decl_ref = try sema.analyzeDeclRef(decl_index); const result = try sema.analyzeLoad(block, src, decl_ref, src); if (Air.refToIndex(result)) |index| { if (sema.air_instructions.items(.tag)[index] == .constant and !block.is_typeof) { @@ -26018,6 +26042,19 @@ fn analyzeDeclVal( return result; } +fn addReferencedBy( + sema: *Sema, + block: *Block, + src: LazySrcLoc, + decl_index: Decl.Index, +) !void { + if (sema.mod.comp.reference_trace == @as(u32, 0)) return; + try sema.mod.reference_table.put(sema.gpa, decl_index, .{ + .referencer = block.src_decl, + .src = src, + }); +} + fn ensureDeclAnalyzed(sema: *Sema, decl_index: Decl.Index) CompileError!void { const decl = sema.mod.declPtr(decl_index); if (decl.analysis == .in_progress) { diff --git a/src/main.zig b/src/main.zig index d5a3bce82d..0a83a52fdf 100644 --- a/src/main.zig +++ b/src/main.zig @@ -396,6 +396,8 @@ const usage_build_generic = \\ -fno-Clang Prevent using Clang as the C/C++ compilation backend \\ -fstage1 Force using bootstrap compiler as the codegen backend \\ -fno-stage1 Prevent using bootstrap compiler as the codegen backend + \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error + \\ -fno-reference-trace Disable reference trace \\ -fsingle-threaded Code assumes there is only one thread \\ -fno-single-threaded Code may not assume there is only one thread \\ -fbuiltin Enable implicit builtin knowledge of functions @@ -742,6 +744,7 @@ fn buildOutputType( var headerpad_size: ?u32 = null; var headerpad_max_install_names: bool = false; var dead_strip_dylibs: bool = false; + var reference_trace: ?u32 = null; // e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names. // This array is populated by zig cc frontend and then has to be converted to zig-style @@ -928,14 +931,14 @@ fn buildOutputType( fatal("expected parameter after {s}", .{arg}); }; stack_size_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| { - fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); + fatal("unable to parse stack size '{s}': {s}", .{ next_arg, @errorName(err) }); }; } else if (mem.eql(u8, arg, "--image-base")) { const next_arg = args_iter.next() orelse { fatal("expected parameter after {s}", .{arg}); }; image_base_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| { - fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); + fatal("unable to parse image base override '{s}': {s}", .{ next_arg, @errorName(err) }); }; } else if (mem.eql(u8, arg, "--name")) { provided_name = args_iter.next() orelse { @@ -984,7 +987,7 @@ fn buildOutputType( fatal("expected parameter after {s}", .{arg}); }; pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| { - fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); + fatal("unable to parse pagezero size'{s}': {s}", .{ next_arg, @errorName(err) }); }; } else if (mem.eql(u8, arg, "-search_paths_first")) { search_strategy = .paths_first; @@ -995,7 +998,7 @@ fn buildOutputType( fatal("expected parameter after {s}", .{arg}); }; headerpad_size = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| { - fatal("unable to parser '{s}': {s}", .{ arg, @errorName(err) }); + fatal("unable to parse headerpat size '{s}': {s}", .{ next_arg, @errorName(err) }); }; } else if (mem.eql(u8, arg, "-headerpad_max_install_names")) { headerpad_max_install_names = true; @@ -1214,6 +1217,15 @@ fn buildOutputType( use_stage1 = true; } else if (mem.eql(u8, arg, "-fno-stage1")) { use_stage1 = false; + } else if (mem.eql(u8, arg, "-freference-trace")) { + reference_trace = 256; + } else if (mem.startsWith(u8, arg, "-freference-trace=")) { + const num = arg["-freference-trace=".len..]; + reference_trace = std.fmt.parseUnsigned(u32, num, 10) catch |err| { + fatal("unable to parse reference_trace count '{s}': {s}", .{ num, @errorName(err) }); + }; + } else if (mem.eql(u8, arg, "-fno-reference-trace")) { + reference_trace = null; } else if (mem.eql(u8, arg, "-rdynamic")) { rdynamic = true; } else if (mem.eql(u8, arg, "-fsoname")) { @@ -1785,11 +1797,11 @@ fn buildOutputType( fatal("expected linker arg after '{s}'", .{arg}); } linker_optimization = std.fmt.parseUnsigned(u8, linker_args.items[i], 10) catch |err| { - fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); + fatal("unable to parse optimization level '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); }; } else if (mem.startsWith(u8, arg, "-O")) { linker_optimization = std.fmt.parseUnsigned(u8, arg["-O".len..], 10) catch |err| { - fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); + fatal("unable to parse optimization level '{s}': {s}", .{ arg, @errorName(err) }); }; } else if (mem.eql(u8, arg, "-pagezero_size")) { i += 1; @@ -1798,7 +1810,7 @@ fn buildOutputType( } const next_arg = linker_args.items[i]; pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| { - fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); + fatal("unable to parse pagezero size '{s}': {s}", .{ next_arg, @errorName(err) }); }; } else if (mem.eql(u8, arg, "-headerpad")) { i += 1; @@ -1807,7 +1819,7 @@ fn buildOutputType( } const next_arg = linker_args.items[i]; headerpad_size = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| { - fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); + fatal("unable to parse headerpad size '{s}': {s}", .{ next_arg, @errorName(err) }); }; } else if (mem.eql(u8, arg, "-headerpad_max_install_names")) { headerpad_max_install_names = true; @@ -1899,7 +1911,7 @@ fn buildOutputType( fatal("expected linker arg after '{s}'", .{arg}); } version.major = std.fmt.parseUnsigned(u32, linker_args.items[i], 10) catch |err| { - fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); + fatal("unable to parse major image version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); }; have_version = true; } else if (mem.eql(u8, arg, "--minor-image-version")) { @@ -1908,7 +1920,7 @@ fn buildOutputType( fatal("expected linker arg after '{s}'", .{arg}); } version.minor = std.fmt.parseUnsigned(u32, linker_args.items[i], 10) catch |err| { - fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); + fatal("unable to parse minor image version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); }; have_version = true; } else if (mem.eql(u8, arg, "-e") or mem.eql(u8, arg, "--entry")) { @@ -1923,7 +1935,7 @@ fn buildOutputType( fatal("expected linker arg after '{s}'", .{arg}); } stack_size_override = std.fmt.parseUnsigned(u64, linker_args.items[i], 0) catch |err| { - fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); + fatal("unable to parse stack size override '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); }; } else if (mem.eql(u8, arg, "--image-base")) { i += 1; @@ -1931,7 +1943,7 @@ fn buildOutputType( fatal("expected linker arg after '{s}'", .{arg}); } image_base_override = std.fmt.parseUnsigned(u64, linker_args.items[i], 0) catch |err| { - fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); + fatal("unable to parse image base override '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); }; } else if (mem.eql(u8, arg, "-T") or mem.eql(u8, arg, "--script")) { i += 1; @@ -1984,7 +1996,7 @@ fn buildOutputType( linker_args.items[i], 10, ) catch |err| { - fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); + fatal("unable to parse major subsystem version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); }; } else if (mem.eql(u8, arg, "--minor-subsystem-version")) { i += 1; @@ -1997,7 +2009,7 @@ fn buildOutputType( linker_args.items[i], 10, ) catch |err| { - fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); + fatal("unable to parse minor subsystem version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); }; } else if (mem.eql(u8, arg, "-framework")) { i += 1; @@ -2981,6 +2993,7 @@ fn buildOutputType( .headerpad_size = headerpad_size, .headerpad_max_install_names = headerpad_max_install_names, .dead_strip_dylibs = dead_strip_dylibs, + .reference_trace = reference_trace, }) catch |err| switch (err) { error.LibCUnavailable => { const target = target_info.target; @@ -3740,6 +3753,8 @@ pub const usage_build = \\Options: \\ -fstage1 Force using bootstrap compiler as the codegen backend \\ -fno-stage1 Prevent using bootstrap compiler as the codegen backend + \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error + \\ -fno-reference-trace Disable reference trace \\ --build-file [file] Override path to build.zig \\ --cache-dir [path] Override path to local Zig cache directory \\ --global-cache-dir [path] Override path to global Zig cache directory @@ -3812,6 +3827,12 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi } else if (mem.eql(u8, arg, "-fno-stage1")) { use_stage1 = false; try child_argv.append(arg); + } else if (mem.eql(u8, arg, "-freference-trace")) { + try child_argv.append(arg); + } else if (mem.startsWith(u8, arg, "-freference-trace=")) { + try child_argv.append(arg); + } else if (mem.eql(u8, arg, "-fno-reference-trace")) { + try child_argv.append(arg); } } try child_argv.append(arg); diff --git a/src/test.zig b/src/test.zig index f26c65f3f8..e1cc00fd62 100644 --- a/src/test.zig +++ b/src/test.zig @@ -1548,6 +1548,7 @@ pub const TestContext = struct { .self_exe_path = std.testing.zig_exe_path, // TODO instead of turning off color, pass in a std.Progress.Node .color = .off, + .reference_trace = 0, // TODO: force self-hosted linkers with stage2 backend to avoid LLD creeping in // until the auto-select mechanism deems them worthy .use_lld = switch (case.backend) { diff --git a/test/cases/compile_errors/top_level_decl_dependency_loop.zig b/test/cases/compile_errors/top_level_decl_dependency_loop.zig index 3b0e60ac02..8ba3d98ea2 100644 --- a/test/cases/compile_errors/top_level_decl_dependency_loop.zig +++ b/test/cases/compile_errors/top_level_decl_dependency_loop.zig @@ -10,4 +10,3 @@ export fn entry() void { // target=native // // :1:1: error: dependency loop detected -// :2:19: note: referenced here