authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-10 05:26:59-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-06-10 05:26:59-04:00
logfcfeafe99a3ecc694a3475735c81a0d75b6da6d0
tree55eefb8b42d39c7ead40f9a92e5c494c9b2226b1
parent5816d3eaec3f3bb04e70c89aa402ba9e0e5e7b2c
parent436aafd3e2ef1a8f5998b974a9791b59939f57ad
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11819 from ziglang/std.debug.Trace

introduce std.debug.Trace and use it to debug a LazySrcLoc in stage2 that is set to a bogus value

17 files changed, 365 insertions(+), 136 deletions(-)

build.zig+3
...@@ -131,6 +131,7 @@ pub fn build(b: *Builder) !void {...@@ -131,6 +131,7 @@ pub fn build(b: *Builder) !void {
131 const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse enable_llvm;131 const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse enable_llvm;
132 const strip = b.option(bool, "strip", "Omit debug information") orelse false;132 const strip = b.option(bool, "strip", "Omit debug information") orelse false;
133 const use_zig0 = b.option(bool, "zig0", "Bootstrap using zig0") orelse false;133 const use_zig0 = b.option(bool, "zig0", "Bootstrap using zig0") orelse false;
134 const value_tracing = b.option(bool, "value-tracing", "Enable extra state tracking to help troubleshoot bugs in the compiler (using the std.debug.Trace API)") orelse false;
134135
135 const mem_leak_frames: u32 = b.option(u32, "mem-leak-frames", "How many stack frames to print when a memory leak occurs. Tests get 2x this amount.") orelse blk: {136 const mem_leak_frames: u32 = b.option(u32, "mem-leak-frames", "How many stack frames to print when a memory leak occurs. Tests get 2x this amount.") orelse blk: {
136 if (strip) break :blk @as(u32, 0);137 if (strip) break :blk @as(u32, 0);
...@@ -353,6 +354,7 @@ pub fn build(b: *Builder) !void {...@@ -353,6 +354,7 @@ pub fn build(b: *Builder) !void {
353 exe_options.addOption(bool, "enable_tracy", tracy != null);354 exe_options.addOption(bool, "enable_tracy", tracy != null);
354 exe_options.addOption(bool, "enable_tracy_callstack", tracy_callstack);355 exe_options.addOption(bool, "enable_tracy_callstack", tracy_callstack);
355 exe_options.addOption(bool, "enable_tracy_allocation", tracy_allocation);356 exe_options.addOption(bool, "enable_tracy_allocation", tracy_allocation);
357 exe_options.addOption(bool, "value_tracing", value_tracing);
356 exe_options.addOption(bool, "is_stage1", is_stage1);358 exe_options.addOption(bool, "is_stage1", is_stage1);
357 exe_options.addOption(bool, "omit_stage2", omit_stage2);359 exe_options.addOption(bool, "omit_stage2", omit_stage2);
358 if (tracy) |tracy_path| {360 if (tracy) |tracy_path| {
...@@ -402,6 +404,7 @@ pub fn build(b: *Builder) !void {...@@ -402,6 +404,7 @@ pub fn build(b: *Builder) !void {
402 test_cases_options.addOption(bool, "enable_rosetta", b.enable_rosetta);404 test_cases_options.addOption(bool, "enable_rosetta", b.enable_rosetta);
403 test_cases_options.addOption(bool, "enable_darling", b.enable_darling);405 test_cases_options.addOption(bool, "enable_darling", b.enable_darling);
404 test_cases_options.addOption(u32, "mem_leak_frames", mem_leak_frames * 2);406 test_cases_options.addOption(u32, "mem_leak_frames", mem_leak_frames * 2);
407 test_cases_options.addOption(bool, "value_tracing", value_tracing);
405 test_cases_options.addOption(?[]const u8, "glibc_runtimes_dir", b.glibc_runtimes_dir);408 test_cases_options.addOption(?[]const u8, "glibc_runtimes_dir", b.glibc_runtimes_dir);
406 test_cases_options.addOption([:0]const u8, "version", try b.allocator.dupeZ(u8, version));409 test_cases_options.addOption([:0]const u8, "version", try b.allocator.dupeZ(u8, version));
407 test_cases_options.addOption(std.SemanticVersion, "semver", semver);410 test_cases_options.addOption(std.SemanticVersion, "semver", semver);
ci/azure/build.zig+2
...@@ -99,6 +99,7 @@ pub fn build(b: *Builder) !void {...@@ -99,6 +99,7 @@ pub fn build(b: *Builder) !void {
99 const force_gpa = b.option(bool, "force-gpa", "Force the compiler to use GeneralPurposeAllocator") orelse false;99 const force_gpa = b.option(bool, "force-gpa", "Force the compiler to use GeneralPurposeAllocator") orelse false;
100 const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse enable_llvm;100 const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse enable_llvm;
101 const strip = b.option(bool, "strip", "Omit debug information") orelse false;101 const strip = b.option(bool, "strip", "Omit debug information") orelse false;
102 const value_tracing = b.option(bool, "value-tracing", "Enable extra state tracking to help troubleshoot bugs in the compiler (using the std.debug.Trace API)") orelse false;
102103
103 const mem_leak_frames: u32 = b.option(u32, "mem-leak-frames", "How many stack frames to print when a memory leak occurs. Tests get 2x this amount.") orelse blk: {104 const mem_leak_frames: u32 = b.option(u32, "mem-leak-frames", "How many stack frames to print when a memory leak occurs. Tests get 2x this amount.") orelse blk: {
104 if (strip) break :blk @as(u32, 0);105 if (strip) break :blk @as(u32, 0);
...@@ -303,6 +304,7 @@ pub fn build(b: *Builder) !void {...@@ -303,6 +304,7 @@ pub fn build(b: *Builder) !void {
303 exe_options.addOption(bool, "enable_tracy", tracy != null);304 exe_options.addOption(bool, "enable_tracy", tracy != null);
304 exe_options.addOption(bool, "enable_tracy_callstack", tracy_callstack);305 exe_options.addOption(bool, "enable_tracy_callstack", tracy_callstack);
305 exe_options.addOption(bool, "enable_tracy_allocation", tracy_allocation);306 exe_options.addOption(bool, "enable_tracy_allocation", tracy_allocation);
307 exe_options.addOption(bool, "value_tracing", value_tracing);
306 exe_options.addOption(bool, "is_stage1", is_stage1);308 exe_options.addOption(bool, "is_stage1", is_stage1);
307 exe_options.addOption(bool, "omit_stage2", omit_stage2);309 exe_options.addOption(bool, "omit_stage2", omit_stage2);
308 if (tracy) |tracy_path| {310 if (tracy) |tracy_path| {
lib/std/debug.zig+82
...@@ -1943,3 +1943,85 @@ test "#4353: std.debug should manage resources correctly" {...@@ -1943,3 +1943,85 @@ test "#4353: std.debug should manage resources correctly" {
1943noinline fn showMyTrace() usize {1943noinline fn showMyTrace() usize {
1944 return @returnAddress();1944 return @returnAddress();
1945}1945}
1946
1947/// This API helps you track where a value originated and where it was mutated,
1948/// or any other points of interest.
1949/// In debug mode, it adds a small size penalty (104 bytes on 64-bit architectures)
1950/// to the aggregate that you add it to.
1951/// In release mode, it is size 0 and all methods are no-ops.
1952/// This is a pre-made type with default settings.
1953/// For more advanced usage, see `ConfigurableTrace`.
1954pub const Trace = ConfigurableTrace(2, 4, builtin.mode == .Debug);
1955
1956pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize, comptime enabled: bool) type {
1957 return struct {
1958 addrs: [actual_size][stack_frame_count]usize = undefined,
1959 notes: [actual_size][]const u8 = undefined,
1960 index: Index = 0,
1961
1962 const actual_size = if (enabled) size else 0;
1963 const Index = if (enabled) usize else u0;
1964
1965 pub const enabled = enabled;
1966
1967 pub const add = if (enabled) addNoInline else addNoOp;
1968
1969 pub noinline fn addNoInline(t: *@This(), note: []const u8) void {
1970 comptime assert(enabled);
1971 return addAddr(t, @returnAddress(), note);
1972 }
1973
1974 pub inline fn addNoOp(t: *@This(), note: []const u8) void {
1975 _ = t;
1976 _ = note;
1977 comptime assert(!enabled);
1978 }
1979
1980 pub fn addAddr(t: *@This(), addr: usize, note: []const u8) void {
1981 if (!enabled) return;
1982
1983 if (t.index < size) {
1984 t.notes[t.index] = note;
1985 t.addrs[t.index] = [1]usize{0} ** stack_frame_count;
1986 var stack_trace: std.builtin.StackTrace = .{
1987 .index = 0,
1988 .instruction_addresses = &t.addrs[t.index],
1989 };
1990 captureStackTrace(addr, &stack_trace);
1991 }
1992 // Keep counting even if the end is reached so that the
1993 // user can find out how much more size they need.
1994 t.index += 1;
1995 }
1996
1997 pub fn dump(t: @This()) void {
1998 if (!enabled) return;
1999
2000 const tty_config = detectTTYConfig();
2001 const stderr = io.getStdErr().writer();
2002 const end = @maximum(t.index, size);
2003 const debug_info = getSelfDebugInfo() catch |err| {
2004 stderr.print(
2005 "Unable to dump stack trace: Unable to open debug info: {s}\n",
2006 .{@errorName(err)},
2007 ) catch return;
2008 return;
2009 };
2010 for (t.addrs[0..end]) |frames_array, i| {
2011 stderr.print("{s}:\n", .{t.notes[i]}) catch return;
2012 var frames_array_mutable = frames_array;
2013 const frames = mem.sliceTo(frames_array_mutable[0..], 0);
2014 const stack_trace: std.builtin.StackTrace = .{
2015 .index = frames.len,
2016 .instruction_addresses = frames,
2017 };
2018 writeStackTrace(stack_trace, stderr, getDebugInfoAllocator(), debug_info, tty_config) catch continue;
2019 }
2020 if (t.index > end) {
2021 stderr.print("{d} more traces not shown; consider increasing trace size\n", .{
2022 t.index - end,
2023 }) catch return;
2024 }
2025 }
2026 };
2027}
src/Compilation.zig+95-6
...@@ -338,6 +338,8 @@ pub const AllErrors = struct {...@@ -338,6 +338,8 @@ pub const AllErrors = struct {
338 line: u32,338 line: u32,
339 column: u32,339 column: u32,
340 byte_offset: u32,340 byte_offset: u32,
341 /// Usually one, but incremented for redundant messages.
342 count: u32 = 1,
341 /// Does not include the trailing newline.343 /// Does not include the trailing newline.
342 source_line: ?[]const u8,344 source_line: ?[]const u8,
343 notes: []Message = &.{},345 notes: []Message = &.{},
...@@ -345,8 +347,21 @@ pub const AllErrors = struct {...@@ -345,8 +347,21 @@ pub const AllErrors = struct {
345 plain: struct {347 plain: struct {
346 msg: []const u8,348 msg: []const u8,
347 notes: []Message = &.{},349 notes: []Message = &.{},
350 /// Usually one, but incremented for redundant messages.
351 count: u32 = 1,
348 },352 },
349353
354 pub fn incrementCount(msg: *Message) void {
355 switch (msg.*) {
356 .src => |*src| {
357 src.count += 1;
358 },
359 .plain => |*plain| {
360 plain.count += 1;
361 },
362 }
363 }
364
350 pub fn renderToStdErr(msg: Message, ttyconf: std.debug.TTY.Config) void {365 pub fn renderToStdErr(msg: Message, ttyconf: std.debug.TTY.Config) void {
351 std.debug.getStderrMutex().lock();366 std.debug.getStderrMutex().lock();
352 defer std.debug.getStderrMutex().unlock();367 defer std.debug.getStderrMutex().unlock();
...@@ -376,7 +391,13 @@ pub const AllErrors = struct {...@@ -376,7 +391,13 @@ pub const AllErrors = struct {
376 try stderr.writeAll(kind);391 try stderr.writeAll(kind);
377 ttyconf.setColor(stderr, .Reset);392 ttyconf.setColor(stderr, .Reset);
378 ttyconf.setColor(stderr, .Bold);393 ttyconf.setColor(stderr, .Bold);
379 try stderr.print(" {s}\n", .{src.msg});394 if (src.count == 1) {
395 try stderr.print(" {s}\n", .{src.msg});
396 } else {
397 try stderr.print(" {s}", .{src.msg});
398 ttyconf.setColor(stderr, .Dim);
399 try stderr.print(" ({d} times)\n", .{src.count});
400 }
380 ttyconf.setColor(stderr, .Reset);401 ttyconf.setColor(stderr, .Reset);
381 if (ttyconf != .no_color) {402 if (ttyconf != .no_color) {
382 if (src.source_line) |line| {403 if (src.source_line) |line| {
...@@ -400,7 +421,13 @@ pub const AllErrors = struct {...@@ -400,7 +421,13 @@ pub const AllErrors = struct {
400 try stderr.writeByteNTimes(' ', indent);421 try stderr.writeByteNTimes(' ', indent);
401 try stderr.writeAll(kind);422 try stderr.writeAll(kind);
402 ttyconf.setColor(stderr, .Reset);423 ttyconf.setColor(stderr, .Reset);
403 try stderr.print(" {s}\n", .{plain.msg});424 if (plain.count == 1) {
425 try stderr.print(" {s}\n", .{plain.msg});
426 } else {
427 try stderr.print(" {s}", .{plain.msg});
428 ttyconf.setColor(stderr, .Dim);
429 try stderr.print(" ({d} times)\n", .{plain.count});
430 }
404 ttyconf.setColor(stderr, .Reset);431 ttyconf.setColor(stderr, .Reset);
405 for (plain.notes) |note| {432 for (plain.notes) |note| {
406 try note.renderToStdErrInner(ttyconf, stderr_file, "error:", .Red, indent + 4);433 try note.renderToStdErrInner(ttyconf, stderr_file, "error:", .Red, indent + 4);
...@@ -408,6 +435,50 @@ pub const AllErrors = struct {...@@ -408,6 +435,50 @@ pub const AllErrors = struct {
408 },435 },
409 }436 }
410 }437 }
438
439 pub const HashContext = struct {
440 pub fn hash(ctx: HashContext, key: *Message) u64 {
441 _ = ctx;
442 var hasher = std.hash.Wyhash.init(0);
443
444 switch (key.*) {
445 .src => |src| {
446 hasher.update(src.msg);
447 hasher.update(src.src_path);
448 std.hash.autoHash(&hasher, src.line);
449 std.hash.autoHash(&hasher, src.column);
450 std.hash.autoHash(&hasher, src.byte_offset);
451 },
452 .plain => |plain| {
453 hasher.update(plain.msg);
454 },
455 }
456
457 return hasher.final();
458 }
459
460 pub fn eql(ctx: HashContext, a: *Message, b: *Message) bool {
461 _ = ctx;
462 switch (a.*) {
463 .src => |a_src| switch (b.*) {
464 .src => |b_src| {
465 return mem.eql(u8, a_src.msg, b_src.msg) and
466 mem.eql(u8, a_src.src_path, b_src.src_path) and
467 a_src.line == b_src.line and
468 a_src.column == b_src.column and
469 a_src.byte_offset == b_src.byte_offset;
470 },
471 .plain => return false,
472 },
473 .plain => |a_plain| switch (b.*) {
474 .src => return false,
475 .plain => |b_plain| {
476 return mem.eql(u8, a_plain.msg, b_plain.msg);
477 },
478 },
479 }
480 }
481 };
411 };482 };
412483
413 pub fn deinit(self: *AllErrors, gpa: Allocator) void {484 pub fn deinit(self: *AllErrors, gpa: Allocator) void {
...@@ -421,13 +492,25 @@ pub const AllErrors = struct {...@@ -421,13 +492,25 @@ pub const AllErrors = struct {
421 module_err_msg: Module.ErrorMsg,492 module_err_msg: Module.ErrorMsg,
422 ) !void {493 ) !void {
423 const allocator = arena.allocator();494 const allocator = arena.allocator();
424 const notes = try allocator.alloc(Message, module_err_msg.notes.len);495
425 for (notes) |*note, i| {496 const notes_buf = try allocator.alloc(Message, module_err_msg.notes.len);
426 const module_note = module_err_msg.notes[i];497 var note_i: usize = 0;
498
499 // De-duplicate error notes. The main use case in mind for this is
500 // too many "note: called from here" notes when eval branch quota is reached.
501 var seen_notes = std.HashMap(
502 *Message,
503 void,
504 Message.HashContext,
505 std.hash_map.default_max_load_percentage,
506 ).init(allocator);
507
508 for (module_err_msg.notes) |module_note| {
427 const source = try module_note.src_loc.file_scope.getSource(module.gpa);509 const source = try module_note.src_loc.file_scope.getSource(module.gpa);
428 const byte_offset = try module_note.src_loc.byteOffset(module.gpa);510 const byte_offset = try module_note.src_loc.byteOffset(module.gpa);
429 const loc = std.zig.findLineColumn(source.bytes, byte_offset);511 const loc = std.zig.findLineColumn(source.bytes, byte_offset);
430 const file_path = try module_note.src_loc.file_scope.fullPath(allocator);512 const file_path = try module_note.src_loc.file_scope.fullPath(allocator);
513 const note = &notes_buf[note_i];
431 note.* = .{514 note.* = .{
432 .src = .{515 .src = .{
433 .src_path = file_path,516 .src_path = file_path,
...@@ -438,6 +521,12 @@ pub const AllErrors = struct {...@@ -438,6 +521,12 @@ pub const AllErrors = struct {
438 .source_line = try allocator.dupe(u8, loc.source_line),521 .source_line = try allocator.dupe(u8, loc.source_line),
439 },522 },
440 };523 };
524 const gop = try seen_notes.getOrPut(note);
525 if (gop.found_existing) {
526 gop.key_ptr.*.incrementCount();
527 } else {
528 note_i += 1;
529 }
441 }530 }
442 if (module_err_msg.src_loc.lazy == .entire_file) {531 if (module_err_msg.src_loc.lazy == .entire_file) {
443 try errors.append(.{532 try errors.append(.{
...@@ -458,7 +547,7 @@ pub const AllErrors = struct {...@@ -458,7 +547,7 @@ pub const AllErrors = struct {
458 .byte_offset = byte_offset,547 .byte_offset = byte_offset,
459 .line = @intCast(u32, loc.line),548 .line = @intCast(u32, loc.line),
460 .column = @intCast(u32, loc.column),549 .column = @intCast(u32, loc.column),
461 .notes = notes,550 .notes = notes_buf[0..note_i],
462 .source_line = try allocator.dupe(u8, loc.source_line),551 .source_line = try allocator.dupe(u8, loc.source_line),
463 },552 },
464 });553 });
src/Module.zig+61-30
...@@ -659,7 +659,7 @@ pub const Decl = struct {...@@ -659,7 +659,7 @@ pub const Decl = struct {
659 }659 }
660660
661 pub fn nodeSrcLoc(decl: Decl, node_index: Ast.Node.Index) LazySrcLoc {661 pub fn nodeSrcLoc(decl: Decl, node_index: Ast.Node.Index) LazySrcLoc {
662 return .{ .node_offset = decl.nodeIndexToRelative(node_index) };662 return LazySrcLoc.nodeOffset(decl.nodeIndexToRelative(node_index));
663 }663 }
664664
665 pub fn srcLoc(decl: Decl) SrcLoc {665 pub fn srcLoc(decl: Decl) SrcLoc {
...@@ -670,7 +670,7 @@ pub const Decl = struct {...@@ -670,7 +670,7 @@ pub const Decl = struct {
670 return .{670 return .{
671 .file_scope = decl.getFileScope(),671 .file_scope = decl.getFileScope(),
672 .parent_decl_node = decl.src_node,672 .parent_decl_node = decl.src_node,
673 .lazy = .{ .node_offset = node_offset },673 .lazy = LazySrcLoc.nodeOffset(node_offset),
674 };674 };
675 }675 }
676676
...@@ -861,7 +861,7 @@ pub const ErrorSet = struct {...@@ -861,7 +861,7 @@ pub const ErrorSet = struct {
861 return .{861 return .{
862 .file_scope = owner_decl.getFileScope(),862 .file_scope = owner_decl.getFileScope(),
863 .parent_decl_node = owner_decl.src_node,863 .parent_decl_node = owner_decl.src_node,
864 .lazy = .{ .node_offset = self.node_offset },864 .lazy = LazySrcLoc.nodeOffset(self.node_offset),
865 };865 };
866 }866 }
867867
...@@ -947,7 +947,7 @@ pub const Struct = struct {...@@ -947,7 +947,7 @@ pub const Struct = struct {
947 return .{947 return .{
948 .file_scope = owner_decl.getFileScope(),948 .file_scope = owner_decl.getFileScope(),
949 .parent_decl_node = owner_decl.src_node,949 .parent_decl_node = owner_decl.src_node,
950 .lazy = .{ .node_offset = s.node_offset },950 .lazy = LazySrcLoc.nodeOffset(s.node_offset),
951 };951 };
952 }952 }
953953
...@@ -1066,7 +1066,7 @@ pub const EnumSimple = struct {...@@ -1066,7 +1066,7 @@ pub const EnumSimple = struct {
1066 return .{1066 return .{
1067 .file_scope = owner_decl.getFileScope(),1067 .file_scope = owner_decl.getFileScope(),
1068 .parent_decl_node = owner_decl.src_node,1068 .parent_decl_node = owner_decl.src_node,
1069 .lazy = .{ .node_offset = self.node_offset },1069 .lazy = LazySrcLoc.nodeOffset(self.node_offset),
1070 };1070 };
1071 }1071 }
1072};1072};
...@@ -1097,7 +1097,7 @@ pub const EnumNumbered = struct {...@@ -1097,7 +1097,7 @@ pub const EnumNumbered = struct {
1097 return .{1097 return .{
1098 .file_scope = owner_decl.getFileScope(),1098 .file_scope = owner_decl.getFileScope(),
1099 .parent_decl_node = owner_decl.src_node,1099 .parent_decl_node = owner_decl.src_node,
1100 .lazy = .{ .node_offset = self.node_offset },1100 .lazy = LazySrcLoc.nodeOffset(self.node_offset),
1101 };1101 };
1102 }1102 }
1103};1103};
...@@ -1131,7 +1131,7 @@ pub const EnumFull = struct {...@@ -1131,7 +1131,7 @@ pub const EnumFull = struct {
1131 return .{1131 return .{
1132 .file_scope = owner_decl.getFileScope(),1132 .file_scope = owner_decl.getFileScope(),
1133 .parent_decl_node = owner_decl.src_node,1133 .parent_decl_node = owner_decl.src_node,
1134 .lazy = .{ .node_offset = self.node_offset },1134 .lazy = LazySrcLoc.nodeOffset(self.node_offset),
1135 };1135 };
1136 }1136 }
1137};1137};
...@@ -1197,7 +1197,7 @@ pub const Union = struct {...@@ -1197,7 +1197,7 @@ pub const Union = struct {
1197 return .{1197 return .{
1198 .file_scope = owner_decl.getFileScope(),1198 .file_scope = owner_decl.getFileScope(),
1199 .parent_decl_node = owner_decl.src_node,1199 .parent_decl_node = owner_decl.src_node,
1200 .lazy = .{ .node_offset = self.node_offset },1200 .lazy = LazySrcLoc.nodeOffset(self.node_offset),
1201 };1201 };
1202 }1202 }
12031203
...@@ -1404,7 +1404,7 @@ pub const Opaque = struct {...@@ -1404,7 +1404,7 @@ pub const Opaque = struct {
1404 return .{1404 return .{
1405 .file_scope = owner_decl.getFileScope(),1405 .file_scope = owner_decl.getFileScope(),
1406 .parent_decl_node = owner_decl.src_node,1406 .parent_decl_node = owner_decl.src_node,
1407 .lazy = .{ .node_offset = self.node_offset },1407 .lazy = LazySrcLoc.nodeOffset(self.node_offset),
1408 };1408 };
1409 }1409 }
14101410
...@@ -2105,7 +2105,17 @@ pub const SrcLoc = struct {...@@ -2105,7 +2105,17 @@ pub const SrcLoc = struct {
2105 const token_starts = tree.tokens.items(.start);2105 const token_starts = tree.tokens.items(.start);
2106 return token_starts[tok_index];2106 return token_starts[tok_index];
2107 },2107 },
2108 .node_offset, .node_offset_bin_op => |node_off| {2108 .node_offset => |traced_off| {
2109 const node_off = traced_off.x;
2110 const tree = try src_loc.file_scope.getTree(gpa);
2111 const node = src_loc.declRelativeToNodeIndex(node_off);
2112 assert(src_loc.file_scope.tree_loaded);
2113 const main_tokens = tree.nodes.items(.main_token);
2114 const tok_index = main_tokens[node];
2115 const token_starts = tree.tokens.items(.start);
2116 return token_starts[tok_index];
2117 },
2118 .node_offset_bin_op => |node_off| {
2109 const tree = try src_loc.file_scope.getTree(gpa);2119 const tree = try src_loc.file_scope.getTree(gpa);
2110 const node = src_loc.declRelativeToNodeIndex(node_off);2120 const node = src_loc.declRelativeToNodeIndex(node_off);
2111 assert(src_loc.file_scope.tree_loaded);2121 assert(src_loc.file_scope.tree_loaded);
...@@ -2515,6 +2525,15 @@ pub const SrcLoc = struct {...@@ -2515,6 +2525,15 @@ pub const SrcLoc = struct {
2515 }2525 }
2516};2526};
25172527
2528/// This wraps a simple integer in debug builds so that later on we can find out
2529/// where in semantic analysis the value got set.
2530const TracedOffset = struct {
2531 x: i32,
2532 trace: std.debug.Trace = .{},
2533
2534 const want_tracing = build_options.value_tracing;
2535};
2536
2518/// Resolving a source location into a byte offset may require doing work2537/// Resolving a source location into a byte offset may require doing work
2519/// that we would rather not do unless the error actually occurs.2538/// that we would rather not do unless the error actually occurs.
2520/// Therefore we need a data structure that contains the information necessary2539/// Therefore we need a data structure that contains the information necessary
...@@ -2555,7 +2574,7 @@ pub const LazySrcLoc = union(enum) {...@@ -2555,7 +2574,7 @@ pub const LazySrcLoc = union(enum) {
2555 /// The source location points to an AST node, which is this value offset2574 /// The source location points to an AST node, which is this value offset
2556 /// from its containing Decl node AST index.2575 /// from its containing Decl node AST index.
2557 /// The Decl is determined contextually.2576 /// The Decl is determined contextually.
2558 node_offset: i32,2577 node_offset: TracedOffset,
2559 /// The source location points to two tokens left of the first token of an AST node,2578 /// The source location points to two tokens left of the first token of an AST node,
2560 /// which is this value offset from its containing Decl node AST index.2579 /// which is this value offset from its containing Decl node AST index.
2561 /// The Decl is determined contextually.2580 /// The Decl is determined contextually.
...@@ -2705,6 +2724,18 @@ pub const LazySrcLoc = union(enum) {...@@ -2705,6 +2724,18 @@ pub const LazySrcLoc = union(enum) {
2705 /// The Decl is determined contextually.2724 /// The Decl is determined contextually.
2706 node_offset_array_type_elem: i32,2725 node_offset_array_type_elem: i32,
27072726
2727 pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease;
2728
2729 noinline fn nodeOffsetDebug(node_offset: i32) LazySrcLoc {
2730 var result: LazySrcLoc = .{ .node_offset = .{ .x = node_offset } };
2731 result.node_offset.trace.addAddr(@returnAddress(), "init");
2732 return result;
2733 }
2734
2735 fn nodeOffsetRelease(node_offset: i32) LazySrcLoc {
2736 return .{ .node_offset = .{ .x = node_offset } };
2737 }
2738
2708 /// Upgrade to a `SrcLoc` based on the `Decl` provided.2739 /// Upgrade to a `SrcLoc` based on the `Decl` provided.
2709 pub fn toSrcLoc(lazy: LazySrcLoc, decl: *Decl) SrcLoc {2740 pub fn toSrcLoc(lazy: LazySrcLoc, decl: *Decl) SrcLoc {
2710 return switch (lazy) {2741 return switch (lazy) {
...@@ -4014,7 +4045,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4014,7 +4045,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4014 const body = zir.extra[extra.end..][0..extra.data.body_len];4045 const body = zir.extra[extra.end..][0..extra.data.body_len];
4015 const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand;4046 const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand;
4016 try wip_captures.finalize();4047 try wip_captures.finalize();
4017 const src: LazySrcLoc = .{ .node_offset = 0 };4048 const src = LazySrcLoc.nodeOffset(0);
4018 const decl_tv = try sema.resolveInstValue(&block_scope, src, result_ref);4049 const decl_tv = try sema.resolveInstValue(&block_scope, src, result_ref);
4019 const decl_align: u32 = blk: {4050 const decl_align: u32 = blk: {
4020 const align_ref = decl.zirAlignRef();4051 const align_ref = decl.zirAlignRef();
...@@ -5044,7 +5075,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {...@@ -5044,7 +5075,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
5044 // Crucially, this happens *after* we set the function state to success above,5075 // Crucially, this happens *after* we set the function state to success above,
5045 // so that dependencies on the function body will now be satisfied rather than5076 // so that dependencies on the function body will now be satisfied rather than
5046 // result in circular dependency errors.5077 // result in circular dependency errors.
5047 const src: LazySrcLoc = .{ .node_offset = 0 };5078 const src = LazySrcLoc.nodeOffset(0);
5048 sema.resolveFnTypes(&inner_block, src, fn_ty_info) catch |err| switch (err) {5079 sema.resolveFnTypes(&inner_block, src, fn_ty_info) catch |err| switch (err) {
5049 error.NeededSourceLocation => unreachable,5080 error.NeededSourceLocation => unreachable,
5050 error.GenericPoison => unreachable,5081 error.GenericPoison => unreachable,
...@@ -5338,7 +5369,7 @@ pub const SwitchProngSrc = union(enum) {...@@ -5338,7 +5369,7 @@ pub const SwitchProngSrc = union(enum) {
5338 log.warn("unable to load {s}: {s}", .{5369 log.warn("unable to load {s}: {s}", .{
5339 decl.getFileScope().sub_file_path, @errorName(err),5370 decl.getFileScope().sub_file_path, @errorName(err),
5340 });5371 });
5341 return LazySrcLoc{ .node_offset = 0 };5372 return LazySrcLoc.nodeOffset(0);
5342 };5373 };
5343 const switch_node = decl.relativeToNodeIndex(switch_node_offset);5374 const switch_node = decl.relativeToNodeIndex(switch_node_offset);
5344 const main_tokens = tree.nodes.items(.main_token);5375 const main_tokens = tree.nodes.items(.main_token);
...@@ -5367,17 +5398,17 @@ pub const SwitchProngSrc = union(enum) {...@@ -5367,17 +5398,17 @@ pub const SwitchProngSrc = union(enum) {
5367 node_tags[case.ast.values[0]] == .switch_range;5398 node_tags[case.ast.values[0]] == .switch_range;
53685399
5369 switch (prong_src) {5400 switch (prong_src) {
5370 .scalar => |i| if (!is_multi and i == scalar_i) return LazySrcLoc{5401 .scalar => |i| if (!is_multi and i == scalar_i) return LazySrcLoc.nodeOffset(
5371 .node_offset = decl.nodeIndexToRelative(case.ast.values[0]),5402 decl.nodeIndexToRelative(case.ast.values[0]),
5372 },5403 ),
5373 .multi => |s| if (is_multi and s.prong == multi_i) {5404 .multi => |s| if (is_multi and s.prong == multi_i) {
5374 var item_i: u32 = 0;5405 var item_i: u32 = 0;
5375 for (case.ast.values) |item_node| {5406 for (case.ast.values) |item_node| {
5376 if (node_tags[item_node] == .switch_range) continue;5407 if (node_tags[item_node] == .switch_range) continue;
53775408
5378 if (item_i == s.item) return LazySrcLoc{5409 if (item_i == s.item) return LazySrcLoc.nodeOffset(
5379 .node_offset = decl.nodeIndexToRelative(item_node),5410 decl.nodeIndexToRelative(item_node),
5380 };5411 );
5381 item_i += 1;5412 item_i += 1;
5382 } else unreachable;5413 } else unreachable;
5383 },5414 },
...@@ -5387,15 +5418,15 @@ pub const SwitchProngSrc = union(enum) {...@@ -5387,15 +5418,15 @@ pub const SwitchProngSrc = union(enum) {
5387 if (node_tags[range] != .switch_range) continue;5418 if (node_tags[range] != .switch_range) continue;
53885419
5389 if (range_i == s.item) switch (range_expand) {5420 if (range_i == s.item) switch (range_expand) {
5390 .none => return LazySrcLoc{5421 .none => return LazySrcLoc.nodeOffset(
5391 .node_offset = decl.nodeIndexToRelative(range),5422 decl.nodeIndexToRelative(range),
5392 },5423 ),
5393 .first => return LazySrcLoc{5424 .first => return LazySrcLoc.nodeOffset(
5394 .node_offset = decl.nodeIndexToRelative(node_datas[range].lhs),5425 decl.nodeIndexToRelative(node_datas[range].lhs),
5395 },5426 ),
5396 .last => return LazySrcLoc{5427 .last => return LazySrcLoc.nodeOffset(
5397 .node_offset = decl.nodeIndexToRelative(node_datas[range].rhs),5428 decl.nodeIndexToRelative(node_datas[range].rhs),
5398 },5429 ),
5399 };5430 };
5400 range_i += 1;5431 range_i += 1;
5401 } else unreachable;5432 } else unreachable;
...@@ -5450,7 +5481,7 @@ pub const PeerTypeCandidateSrc = union(enum) {...@@ -5450,7 +5481,7 @@ pub const PeerTypeCandidateSrc = union(enum) {
5450 log.warn("unable to load {s}: {s}", .{5481 log.warn("unable to load {s}: {s}", .{
5451 decl.getFileScope().sub_file_path, @errorName(err),5482 decl.getFileScope().sub_file_path, @errorName(err),
5452 });5483 });
5453 return LazySrcLoc{ .node_offset = 0 };5484 return LazySrcLoc.nodeOffset(0);
5454 };5485 };
5455 const node = decl.relativeToNodeIndex(node_offset);5486 const node = decl.relativeToNodeIndex(node_offset);
5456 const node_datas = tree.nodes.items(.data);5487 const node_datas = tree.nodes.items(.data);
src/Sema.zig+45-46
...@@ -1154,7 +1154,7 @@ fn analyzeBodyInner(...@@ -1154,7 +1154,7 @@ fn analyzeBodyInner(
1154 .repeat => {1154 .repeat => {
1155 if (block.is_comptime) {1155 if (block.is_comptime) {
1156 // Send comptime control flow back to the beginning of this block.1156 // Send comptime control flow back to the beginning of this block.
1157 const src: LazySrcLoc = .{ .node_offset = datas[inst].node };1157 const src = LazySrcLoc.nodeOffset(datas[inst].node);
1158 try sema.emitBackwardBranch(block, src);1158 try sema.emitBackwardBranch(block, src);
1159 if (wip_captures.scope.captures.count() != orig_captures) {1159 if (wip_captures.scope.captures.count() != orig_captures) {
1160 try wip_captures.reset(parent_capture_scope);1160 try wip_captures.reset(parent_capture_scope);
...@@ -1165,14 +1165,14 @@ fn analyzeBodyInner(...@@ -1165,14 +1165,14 @@ fn analyzeBodyInner(
1165 continue;1165 continue;
1166 } else {1166 } else {
1167 const src_node = sema.code.instructions.items(.data)[inst].node;1167 const src_node = sema.code.instructions.items(.data)[inst].node;
1168 const src: LazySrcLoc = .{ .node_offset = src_node };1168 const src = LazySrcLoc.nodeOffset(src_node);
1169 try sema.requireRuntimeBlock(block, src);1169 try sema.requireRuntimeBlock(block, src);
1170 break always_noreturn;1170 break always_noreturn;
1171 }1171 }
1172 },1172 },
1173 .repeat_inline => {1173 .repeat_inline => {
1174 // Send comptime control flow back to the beginning of this block.1174 // Send comptime control flow back to the beginning of this block.
1175 const src: LazySrcLoc = .{ .node_offset = datas[inst].node };1175 const src = LazySrcLoc.nodeOffset(datas[inst].node);
1176 try sema.emitBackwardBranch(block, src);1176 try sema.emitBackwardBranch(block, src);
1177 if (wip_captures.scope.captures.count() != orig_captures) {1177 if (wip_captures.scope.captures.count() != orig_captures) {
1178 try wip_captures.reset(parent_capture_scope);1178 try wip_captures.reset(parent_capture_scope);
...@@ -2087,7 +2087,7 @@ fn zirStructDecl(...@@ -2087,7 +2087,7 @@ fn zirStructDecl(
2087 const small = @bitCast(Zir.Inst.StructDecl.Small, extended.small);2087 const small = @bitCast(Zir.Inst.StructDecl.Small, extended.small);
2088 const src: LazySrcLoc = if (small.has_src_node) blk: {2088 const src: LazySrcLoc = if (small.has_src_node) blk: {
2089 const node_offset = @bitCast(i32, sema.code.extra[extended.operand]);2089 const node_offset = @bitCast(i32, sema.code.extra[extended.operand]);
2090 break :blk .{ .node_offset = node_offset };2090 break :blk LazySrcLoc.nodeOffset(node_offset);
2091 } else sema.src;2091 } else sema.src;
20922092
2093 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);2093 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
...@@ -2108,7 +2108,7 @@ fn zirStructDecl(...@@ -2108,7 +2108,7 @@ fn zirStructDecl(
2108 struct_obj.* = .{2108 struct_obj.* = .{
2109 .owner_decl = new_decl_index,2109 .owner_decl = new_decl_index,
2110 .fields = .{},2110 .fields = .{},
2111 .node_offset = src.node_offset,2111 .node_offset = src.node_offset.x,
2112 .zir_index = inst,2112 .zir_index = inst,
2113 .layout = small.layout,2113 .layout = small.layout,
2114 .status = .none,2114 .status = .none,
...@@ -2210,7 +2210,7 @@ fn zirEnumDecl(...@@ -2210,7 +2210,7 @@ fn zirEnumDecl(
2210 const src: LazySrcLoc = if (small.has_src_node) blk: {2210 const src: LazySrcLoc = if (small.has_src_node) blk: {
2211 const node_offset = @bitCast(i32, sema.code.extra[extra_index]);2211 const node_offset = @bitCast(i32, sema.code.extra[extra_index]);
2212 extra_index += 1;2212 extra_index += 1;
2213 break :blk .{ .node_offset = node_offset };2213 break :blk LazySrcLoc.nodeOffset(node_offset);
2214 } else sema.src;2214 } else sema.src;
22152215
2216 const tag_type_ref = if (small.has_tag_type) blk: {2216 const tag_type_ref = if (small.has_tag_type) blk: {
...@@ -2263,7 +2263,7 @@ fn zirEnumDecl(...@@ -2263,7 +2263,7 @@ fn zirEnumDecl(
2263 .tag_ty_inferred = true,2263 .tag_ty_inferred = true,
2264 .fields = .{},2264 .fields = .{},
2265 .values = .{},2265 .values = .{},
2266 .node_offset = src.node_offset,2266 .node_offset = src.node_offset.x,
2267 .namespace = .{2267 .namespace = .{
2268 .parent = block.namespace,2268 .parent = block.namespace,
2269 .ty = enum_ty,2269 .ty = enum_ty,
...@@ -2385,8 +2385,8 @@ fn zirEnumDecl(...@@ -2385,8 +2385,8 @@ fn zirEnumDecl(
2385 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);2385 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);
2386 if (gop.found_existing) {2386 if (gop.found_existing) {
2387 const tree = try sema.getAstTree(block);2387 const tree = try sema.getAstTree(block);
2388 const field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset, field_i);2388 const field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, field_i);
2389 const other_tag_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset, gop.index);2389 const other_tag_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, gop.index);
2390 const msg = msg: {2390 const msg = msg: {
2391 const msg = try sema.errMsg(block, field_src, "duplicate enum tag", .{});2391 const msg = try sema.errMsg(block, field_src, "duplicate enum tag", .{});
2392 errdefer msg.destroy(gpa);2392 errdefer msg.destroy(gpa);
...@@ -2442,7 +2442,7 @@ fn zirUnionDecl(...@@ -2442,7 +2442,7 @@ fn zirUnionDecl(
2442 const src: LazySrcLoc = if (small.has_src_node) blk: {2442 const src: LazySrcLoc = if (small.has_src_node) blk: {
2443 const node_offset = @bitCast(i32, sema.code.extra[extra_index]);2443 const node_offset = @bitCast(i32, sema.code.extra[extra_index]);
2444 extra_index += 1;2444 extra_index += 1;
2445 break :blk .{ .node_offset = node_offset };2445 break :blk LazySrcLoc.nodeOffset(node_offset);
2446 } else sema.src;2446 } else sema.src;
24472447
2448 extra_index += @boolToInt(small.has_tag_type);2448 extra_index += @boolToInt(small.has_tag_type);
...@@ -2480,7 +2480,7 @@ fn zirUnionDecl(...@@ -2480,7 +2480,7 @@ fn zirUnionDecl(
2480 .owner_decl = new_decl_index,2480 .owner_decl = new_decl_index,
2481 .tag_ty = Type.initTag(.@"null"),2481 .tag_ty = Type.initTag(.@"null"),
2482 .fields = .{},2482 .fields = .{},
2483 .node_offset = src.node_offset,2483 .node_offset = src.node_offset.x,
2484 .zir_index = inst,2484 .zir_index = inst,
2485 .layout = small.layout,2485 .layout = small.layout,
2486 .status = .none,2486 .status = .none,
...@@ -2516,7 +2516,7 @@ fn zirOpaqueDecl(...@@ -2516,7 +2516,7 @@ fn zirOpaqueDecl(
2516 const src: LazySrcLoc = if (small.has_src_node) blk: {2516 const src: LazySrcLoc = if (small.has_src_node) blk: {
2517 const node_offset = @bitCast(i32, sema.code.extra[extra_index]);2517 const node_offset = @bitCast(i32, sema.code.extra[extra_index]);
2518 extra_index += 1;2518 extra_index += 1;
2519 break :blk .{ .node_offset = node_offset };2519 break :blk LazySrcLoc.nodeOffset(node_offset);
2520 } else sema.src;2520 } else sema.src;
25212521
2522 const decls_len = if (small.has_decls_len) blk: {2522 const decls_len = if (small.has_decls_len) blk: {
...@@ -2547,7 +2547,7 @@ fn zirOpaqueDecl(...@@ -2547,7 +2547,7 @@ fn zirOpaqueDecl(
25472547
2548 opaque_obj.* = .{2548 opaque_obj.* = .{
2549 .owner_decl = new_decl_index,2549 .owner_decl = new_decl_index,
2550 .node_offset = src.node_offset,2550 .node_offset = src.node_offset.x,
2551 .namespace = .{2551 .namespace = .{
2552 .parent = block.namespace,2552 .parent = block.namespace,
2553 .ty = opaque_ty,2553 .ty = opaque_ty,
...@@ -2623,7 +2623,7 @@ fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -2623,7 +2623,7 @@ fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2623 defer tracy.end();2623 defer tracy.end();
26242624
2625 const inst_data = sema.code.instructions.items(.data)[inst].node;2625 const inst_data = sema.code.instructions.items(.data)[inst].node;
2626 const src: LazySrcLoc = .{ .node_offset = inst_data };2626 const src = LazySrcLoc.nodeOffset(inst_data);
2627 try sema.requireFunctionBlock(block, src);2627 try sema.requireFunctionBlock(block, src);
26282628
2629 if (block.is_comptime or try sema.typeRequiresComptime(block, src, sema.fn_ret_ty)) {2629 if (block.is_comptime or try sema.typeRequiresComptime(block, src, sema.fn_ret_ty)) {
...@@ -2661,7 +2661,7 @@ fn zirRetType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -2661,7 +2661,7 @@ fn zirRetType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2661 defer tracy.end();2661 defer tracy.end();
26622662
2663 const inst_data = sema.code.instructions.items(.data)[inst].node;2663 const inst_data = sema.code.instructions.items(.data)[inst].node;
2664 const src: LazySrcLoc = .{ .node_offset = inst_data };2664 const src = LazySrcLoc.nodeOffset(inst_data);
2665 try sema.requireFunctionBlock(block, src);2665 try sema.requireFunctionBlock(block, src);
2666 return sema.addType(sema.fn_ret_ty);2666 return sema.addType(sema.fn_ret_ty);
2667}2667}
...@@ -2750,7 +2750,7 @@ fn zirAllocExtended(...@@ -2750,7 +2750,7 @@ fn zirAllocExtended(
2750 extended: Zir.Inst.Extended.InstData,2750 extended: Zir.Inst.Extended.InstData,
2751) CompileError!Air.Inst.Ref {2751) CompileError!Air.Inst.Ref {
2752 const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand);2752 const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand);
2753 const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };2753 const src = LazySrcLoc.nodeOffset(extra.data.src_node);
2754 const ty_src = src; // TODO better source location2754 const ty_src = src; // TODO better source location
2755 const align_src = src; // TODO better source location2755 const align_src = src; // TODO better source location
2756 const small = @bitCast(Zir.Inst.AllocExtended.Small, extended.small);2756 const small = @bitCast(Zir.Inst.AllocExtended.Small, extended.small);
...@@ -2903,7 +2903,7 @@ fn zirAllocInferredComptime(...@@ -2903,7 +2903,7 @@ fn zirAllocInferredComptime(
2903 inferred_alloc_ty: Type,2903 inferred_alloc_ty: Type,
2904) CompileError!Air.Inst.Ref {2904) CompileError!Air.Inst.Ref {
2905 const src_node = sema.code.instructions.items(.data)[inst].node;2905 const src_node = sema.code.instructions.items(.data)[inst].node;
2906 const src: LazySrcLoc = .{ .node_offset = src_node };2906 const src = LazySrcLoc.nodeOffset(src_node);
2907 sema.src = src;2907 sema.src = src;
2908 return sema.addConstant(2908 return sema.addConstant(
2909 inferred_alloc_ty,2909 inferred_alloc_ty,
...@@ -2967,7 +2967,7 @@ fn zirAllocInferred(...@@ -2967,7 +2967,7 @@ fn zirAllocInferred(
2967 defer tracy.end();2967 defer tracy.end();
29682968
2969 const src_node = sema.code.instructions.items(.data)[inst].node;2969 const src_node = sema.code.instructions.items(.data)[inst].node;
2970 const src: LazySrcLoc = .{ .node_offset = src_node };2970 const src = LazySrcLoc.nodeOffset(src_node);
2971 sema.src = src;2971 sema.src = src;
29722972
2973 if (block.is_comptime) {2973 if (block.is_comptime) {
...@@ -3718,7 +3718,7 @@ fn zirValidateArrayInit(...@@ -3718,7 +3718,7 @@ fn zirValidateArrayInit(
37183718
3719 outer: for (instrs) |elem_ptr, i| {3719 outer: for (instrs) |elem_ptr, i| {
3720 const elem_ptr_data = sema.code.instructions.items(.data)[elem_ptr].pl_node;3720 const elem_ptr_data = sema.code.instructions.items(.data)[elem_ptr].pl_node;
3721 const elem_src: LazySrcLoc = .{ .node_offset = elem_ptr_data.src_node };3721 const elem_src = LazySrcLoc.nodeOffset(elem_ptr_data.src_node);
37223722
3723 // Determine whether the value stored to this pointer is comptime-known.3723 // Determine whether the value stored to this pointer is comptime-known.
37243724
...@@ -4203,7 +4203,7 @@ fn zirCompileLog(...@@ -4203,7 +4203,7 @@ fn zirCompileLog(
42034203
4204 const extra = sema.code.extraData(Zir.Inst.NodeMultiOp, extended.operand);4204 const extra = sema.code.extraData(Zir.Inst.NodeMultiOp, extended.operand);
4205 const src_node = extra.data.src_node;4205 const src_node = extra.data.src_node;
4206 const src: LazySrcLoc = .{ .node_offset = src_node };4206 const src = LazySrcLoc.nodeOffset(src_node);
4207 const args = sema.code.refSlice(extra.end, extended.small);4207 const args = sema.code.refSlice(extra.end, extended.small);
42084208
4209 for (args) |arg_ref, i| {4209 for (args) |arg_ref, i| {
...@@ -4707,7 +4707,7 @@ pub fn analyzeExport(...@@ -4707,7 +4707,7 @@ pub fn analyzeExport(
4707fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {4707fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
4708 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;4708 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
4709 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };4709 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
4710 const src: LazySrcLoc = .{ .node_offset = extra.node };4710 const src = LazySrcLoc.nodeOffset(extra.node);
4711 const alignment = try sema.resolveAlign(block, operand_src, extra.operand);4711 const alignment = try sema.resolveAlign(block, operand_src, extra.operand);
4712 if (alignment > 256) {4712 if (alignment > 256) {
4713 return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{4713 return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{
...@@ -5312,7 +5312,7 @@ fn analyzeCall(...@@ -5312,7 +5312,7 @@ fn analyzeCall(
5312 delete_memoized_call_key = true;5312 delete_memoized_call_key = true;
5313 }5313 }
53145314
5315 try sema.emitBackwardBranch(&child_block, call_src);5315 try sema.emitBackwardBranch(block, call_src);
53165316
5317 // Whether this call should be memoized, set to false if the call can mutate5317 // Whether this call should be memoized, set to false if the call can mutate
5318 // comptime state.5318 // comptime state.
...@@ -6988,7 +6988,7 @@ fn funcCommon(...@@ -6988,7 +6988,7 @@ fn funcCommon(
6988 const param_types = try sema.arena.alloc(Type, block.params.items.len);6988 const param_types = try sema.arena.alloc(Type, block.params.items.len);
6989 const comptime_params = try sema.arena.alloc(bool, block.params.items.len);6989 const comptime_params = try sema.arena.alloc(bool, block.params.items.len);
6990 for (block.params.items) |param, i| {6990 for (block.params.items) |param, i| {
6991 const param_src: LazySrcLoc = .{ .node_offset = src_node_offset }; // TODO better src6991 const param_src = LazySrcLoc.nodeOffset(src_node_offset); // TODO better src
6992 param_types[i] = param.ty;6992 param_types[i] = param.ty;
6993 comptime_params[i] = param.is_comptime or6993 comptime_params[i] = param.is_comptime or
6994 try sema.typeRequiresComptime(block, param_src, param.ty);6994 try sema.typeRequiresComptime(block, param_src, param.ty);
...@@ -7378,7 +7378,7 @@ fn zirFieldCallBindNamed(sema: *Sema, block: *Block, extended: Zir.Inst.Extended...@@ -7378,7 +7378,7 @@ fn zirFieldCallBindNamed(sema: *Sema, block: *Block, extended: Zir.Inst.Extended
7378 defer tracy.end();7378 defer tracy.end();
73797379
7380 const extra = sema.code.extraData(Zir.Inst.FieldNamedNode, extended.operand).data;7380 const extra = sema.code.extraData(Zir.Inst.FieldNamedNode, extended.operand).data;
7381 const src: LazySrcLoc = .{ .node_offset = extra.node };7381 const src = LazySrcLoc.nodeOffset(extra.node);
7382 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };7382 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
7383 const object_ptr = try sema.resolveInst(extra.lhs);7383 const object_ptr = try sema.resolveInst(extra.lhs);
7384 const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name);7384 const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name);
...@@ -10088,7 +10088,7 @@ fn zirOverflowArithmetic(...@@ -10088,7 +10088,7 @@ fn zirOverflowArithmetic(
10088 defer tracy.end();10088 defer tracy.end();
1008910089
10090 const extra = sema.code.extraData(Zir.Inst.OverflowArithmetic, extended.operand).data;10090 const extra = sema.code.extraData(Zir.Inst.OverflowArithmetic, extended.operand).data;
10091 const src: LazySrcLoc = .{ .node_offset = extra.node };10091 const src = LazySrcLoc.nodeOffset(extra.node);
1009210092
10093 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };10093 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
10094 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };10094 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
...@@ -11309,7 +11309,7 @@ fn zirAsm(...@@ -11309,7 +11309,7 @@ fn zirAsm(
11309 defer tracy.end();11309 defer tracy.end();
1131011310
11311 const extra = sema.code.extraData(Zir.Inst.Asm, extended.operand);11311 const extra = sema.code.extraData(Zir.Inst.Asm, extended.operand);
11312 const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };11312 const src = LazySrcLoc.nodeOffset(extra.data.src_node);
11313 const ret_ty_src: LazySrcLoc = .{ .node_offset_asm_ret_ty = extra.data.src_node };11313 const ret_ty_src: LazySrcLoc = .{ .node_offset_asm_ret_ty = extra.data.src_node };
11314 const outputs_len = @truncate(u5, extended.small);11314 const outputs_len = @truncate(u5, extended.small);
11315 const inputs_len = @truncate(u5, extended.small >> 5);11315 const inputs_len = @truncate(u5, extended.small >> 5);
...@@ -11761,7 +11761,7 @@ fn zirThis(...@@ -11761,7 +11761,7 @@ fn zirThis(
11761 extended: Zir.Inst.Extended.InstData,11761 extended: Zir.Inst.Extended.InstData,
11762) CompileError!Air.Inst.Ref {11762) CompileError!Air.Inst.Ref {
11763 const this_decl_index = block.namespace.getDeclIndex();11763 const this_decl_index = block.namespace.getDeclIndex();
11764 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };11764 const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand));
11765 return sema.analyzeDeclVal(block, src, this_decl_index);11765 return sema.analyzeDeclVal(block, src, this_decl_index);
11766}11766}
1176711767
...@@ -11815,7 +11815,7 @@ fn zirRetAddr(...@@ -11815,7 +11815,7 @@ fn zirRetAddr(
11815 block: *Block,11815 block: *Block,
11816 extended: Zir.Inst.Extended.InstData,11816 extended: Zir.Inst.Extended.InstData,
11817) CompileError!Air.Inst.Ref {11817) CompileError!Air.Inst.Ref {
11818 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };11818 const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand));
11819 try sema.requireRuntimeBlock(block, src);11819 try sema.requireRuntimeBlock(block, src);
11820 return try block.addNoOp(.ret_addr);11820 return try block.addNoOp(.ret_addr);
11821}11821}
...@@ -11825,7 +11825,7 @@ fn zirFrameAddress(...@@ -11825,7 +11825,7 @@ fn zirFrameAddress(
11825 block: *Block,11825 block: *Block,
11826 extended: Zir.Inst.Extended.InstData,11826 extended: Zir.Inst.Extended.InstData,
11827) CompileError!Air.Inst.Ref {11827) CompileError!Air.Inst.Ref {
11828 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };11828 const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand));
11829 try sema.requireRuntimeBlock(block, src);11829 try sema.requireRuntimeBlock(block, src);
11830 return try block.addNoOp(.frame_addr);11830 return try block.addNoOp(.frame_addr);
11831}11831}
...@@ -11838,7 +11838,7 @@ fn zirBuiltinSrc(...@@ -11838,7 +11838,7 @@ fn zirBuiltinSrc(
11838 const tracy = trace(@src());11838 const tracy = trace(@src());
11839 defer tracy.end();11839 defer tracy.end();
1184011840
11841 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };11841 const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand));
11842 const extra = sema.code.extraData(Zir.Inst.LineColumn, extended.operand).data;11842 const extra = sema.code.extraData(Zir.Inst.LineColumn, extended.operand).data;
11843 const func = sema.func orelse return sema.fail(block, src, "@src outside function", .{});11843 const func = sema.func orelse return sema.fail(block, src, "@src outside function", .{});
11844 const fn_owner_decl = sema.mod.declPtr(func.owner_decl);11844 const fn_owner_decl = sema.mod.declPtr(func.owner_decl);
...@@ -12842,7 +12842,7 @@ fn zirTypeofPeer(...@@ -12842,7 +12842,7 @@ fn zirTypeofPeer(
12842 defer tracy.end();12842 defer tracy.end();
1284312843
12844 const extra = sema.code.extraData(Zir.Inst.TypeOfPeer, extended.operand);12844 const extra = sema.code.extraData(Zir.Inst.TypeOfPeer, extended.operand);
12845 const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };12845 const src = LazySrcLoc.nodeOffset(extra.data.src_node);
12846 const body = sema.code.extra[extra.data.body_index..][0..extra.data.body_len];12846 const body = sema.code.extra[extra.data.body_index..][0..extra.data.body_len];
1284712847
12848 var child_block: Block = .{12848 var child_block: Block = .{
...@@ -14157,7 +14157,7 @@ fn zirErrorReturnTrace(...@@ -14157,7 +14157,7 @@ fn zirErrorReturnTrace(
14157 block: *Block,14157 block: *Block,
14158 extended: Zir.Inst.Extended.InstData,14158 extended: Zir.Inst.Extended.InstData,
14159) CompileError!Air.Inst.Ref {14159) CompileError!Air.Inst.Ref {
14160 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };14160 const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand));
14161 return sema.getErrorReturnTrace(block, src);14161 return sema.getErrorReturnTrace(block, src);
14162}14162}
1416314163
...@@ -14185,7 +14185,7 @@ fn zirFrame(...@@ -14185,7 +14185,7 @@ fn zirFrame(
14185 block: *Block,14185 block: *Block,
14186 extended: Zir.Inst.Extended.InstData,14186 extended: Zir.Inst.Extended.InstData,
14187) CompileError!Air.Inst.Ref {14187) CompileError!Air.Inst.Ref {
14188 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };14188 const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand));
14189 return sema.fail(block, src, "TODO: Sema.zirFrame", .{});14189 return sema.fail(block, src, "TODO: Sema.zirFrame", .{});
14190}14190}
1419114191
...@@ -14629,7 +14629,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -14629,7 +14629,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
14629 .tag_ty_inferred = false,14629 .tag_ty_inferred = false,
14630 .fields = .{},14630 .fields = .{},
14631 .values = .{},14631 .values = .{},
14632 .node_offset = src.node_offset,14632 .node_offset = src.node_offset.x,
14633 .namespace = .{14633 .namespace = .{
14634 .parent = block.namespace,14634 .parent = block.namespace,
14635 .ty = enum_ty,14635 .ty = enum_ty,
...@@ -14711,7 +14711,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -14711,7 +14711,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1471114711
14712 opaque_obj.* = .{14712 opaque_obj.* = .{
14713 .owner_decl = new_decl_index,14713 .owner_decl = new_decl_index,
14714 .node_offset = src.node_offset,14714 .node_offset = src.node_offset.x,
14715 .namespace = .{14715 .namespace = .{
14716 .parent = block.namespace,14716 .parent = block.namespace,
14717 .ty = opaque_ty,14717 .ty = opaque_ty,
...@@ -14763,7 +14763,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -14763,7 +14763,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
14763 .owner_decl = new_decl_index,14763 .owner_decl = new_decl_index,
14764 .tag_ty = Type.initTag(.@"null"),14764 .tag_ty = Type.initTag(.@"null"),
14765 .fields = .{},14765 .fields = .{},
14766 .node_offset = src.node_offset,14766 .node_offset = src.node_offset.x,
14767 .zir_index = inst,14767 .zir_index = inst,
14768 .layout = layout_val.toEnum(std.builtin.Type.ContainerLayout),14768 .layout = layout_val.toEnum(std.builtin.Type.ContainerLayout),
14769 .status = .have_field_types,14769 .status = .have_field_types,
...@@ -14930,7 +14930,7 @@ fn reifyStruct(...@@ -14930,7 +14930,7 @@ fn reifyStruct(
14930 struct_obj.* = .{14930 struct_obj.* = .{
14931 .owner_decl = new_decl_index,14931 .owner_decl = new_decl_index,
14932 .fields = .{},14932 .fields = .{},
14933 .node_offset = src.node_offset,14933 .node_offset = src.node_offset.x,
14934 .zir_index = inst,14934 .zir_index = inst,
14935 .layout = layout_val.toEnum(std.builtin.Type.ContainerLayout),14935 .layout = layout_val.toEnum(std.builtin.Type.ContainerLayout),
14936 .status = .have_field_types,14936 .status = .have_field_types,
...@@ -15130,7 +15130,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15130,7 +15130,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1513015130
15131fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {15131fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
15132 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;15132 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
15133 const src: LazySrcLoc = .{ .node_offset = extra.node };15133 const src = LazySrcLoc.nodeOffset(extra.node);
15134 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };15134 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
15135 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };15135 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
15136 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);15136 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
...@@ -17114,7 +17114,7 @@ fn zirAwaitNosuspend(...@@ -17114,7 +17114,7 @@ fn zirAwaitNosuspend(
17114 extended: Zir.Inst.Extended.InstData,17114 extended: Zir.Inst.Extended.InstData,
17115) CompileError!Air.Inst.Ref {17115) CompileError!Air.Inst.Ref {
17116 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;17116 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
17117 const src: LazySrcLoc = .{ .node_offset = extra.node };17117 const src = LazySrcLoc.nodeOffset(extra.node);
1711817118
17119 return sema.fail(block, src, "TODO: Sema.zirAwaitNosuspend", .{});17119 return sema.fail(block, src, "TODO: Sema.zirAwaitNosuspend", .{});
17120}17120}
...@@ -17443,7 +17443,7 @@ fn zirWasmMemorySize(...@@ -17443,7 +17443,7 @@ fn zirWasmMemorySize(
17443) CompileError!Air.Inst.Ref {17443) CompileError!Air.Inst.Ref {
17444 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;17444 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
17445 const index_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };17445 const index_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
17446 const builtin_src: LazySrcLoc = .{ .node_offset = extra.node };17446 const builtin_src = LazySrcLoc.nodeOffset(extra.node);
17447 const target = sema.mod.getTarget();17447 const target = sema.mod.getTarget();
17448 if (!target.isWasm()) {17448 if (!target.isWasm()) {
17449 return sema.fail(block, builtin_src, "builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});17449 return sema.fail(block, builtin_src, "builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});
...@@ -17466,7 +17466,7 @@ fn zirWasmMemoryGrow(...@@ -17466,7 +17466,7 @@ fn zirWasmMemoryGrow(
17466 extended: Zir.Inst.Extended.InstData,17466 extended: Zir.Inst.Extended.InstData,
17467) CompileError!Air.Inst.Ref {17467) CompileError!Air.Inst.Ref {
17468 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;17468 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
17469 const builtin_src: LazySrcLoc = .{ .node_offset = extra.node };17469 const builtin_src = LazySrcLoc.nodeOffset(extra.node);
17470 const index_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };17470 const index_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
17471 const delta_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };17471 const delta_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
17472 const target = sema.mod.getTarget();17472 const target = sema.mod.getTarget();
...@@ -17534,7 +17534,7 @@ fn zirBuiltinExtern(...@@ -17534,7 +17534,7 @@ fn zirBuiltinExtern(
17534 extended: Zir.Inst.Extended.InstData,17534 extended: Zir.Inst.Extended.InstData,
17535) CompileError!Air.Inst.Ref {17535) CompileError!Air.Inst.Ref {
17536 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;17536 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
17537 const src: LazySrcLoc = .{ .node_offset = extra.node };17537 const src = LazySrcLoc.nodeOffset(extra.node);
17538 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };17538 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
17539 const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };17539 const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
1754017540
...@@ -18061,7 +18061,6 @@ fn safetyPanic(...@@ -18061,7 +18061,6 @@ fn safetyPanic(
18061fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void {18061fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
18062 sema.branch_count += 1;18062 sema.branch_count += 1;
18063 if (sema.branch_count > sema.branch_quota) {18063 if (sema.branch_count > sema.branch_quota) {
18064 // TODO show the "called from here" stack
18065 return sema.fail(block, src, "evaluation exceeded {d} backwards branches", .{sema.branch_quota});18064 return sema.fail(block, src, "evaluation exceeded {d} backwards branches", .{sema.branch_quota});
18066 }18065 }
18067}18066}
...@@ -23586,7 +23585,7 @@ fn semaStructFields(...@@ -23586,7 +23585,7 @@ fn semaStructFields(
23586 const small = @bitCast(Zir.Inst.StructDecl.Small, extended.small);23585 const small = @bitCast(Zir.Inst.StructDecl.Small, extended.small);
23587 var extra_index: usize = extended.operand;23586 var extra_index: usize = extended.operand;
2358823587
23589 const src: LazySrcLoc = .{ .node_offset = struct_obj.node_offset };23588 const src = LazySrcLoc.nodeOffset(struct_obj.node_offset);
23590 extra_index += @boolToInt(small.has_src_node);23589 extra_index += @boolToInt(small.has_src_node);
2359123590
23592 const body_len = if (small.has_body_len) blk: {23591 const body_len = if (small.has_body_len) blk: {
...@@ -23773,7 +23772,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil...@@ -23773,7 +23772,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
23773 const small = @bitCast(Zir.Inst.UnionDecl.Small, extended.small);23772 const small = @bitCast(Zir.Inst.UnionDecl.Small, extended.small);
23774 var extra_index: usize = extended.operand;23773 var extra_index: usize = extended.operand;
2377523774
23776 const src: LazySrcLoc = .{ .node_offset = union_obj.node_offset };23775 const src = LazySrcLoc.nodeOffset(union_obj.node_offset);
23777 extra_index += @boolToInt(small.has_src_node);23776 extra_index += @boolToInt(small.has_src_node);
2377823777
23779 const tag_type_ref: Zir.Inst.Ref = if (small.has_tag_type) blk: {23778 const tag_type_ref: Zir.Inst.Ref = if (small.has_tag_type) blk: {
...@@ -24459,7 +24458,7 @@ fn enumFieldSrcLoc(...@@ -24459,7 +24458,7 @@ fn enumFieldSrcLoc(
24459 .container_field,24458 .container_field,
24460 => {24459 => {
24461 if (it_index == field_index) {24460 if (it_index == field_index) {
24462 return .{ .node_offset = decl.nodeIndexToRelative(member_node) };24461 return LazySrcLoc.nodeOffset(decl.nodeIndexToRelative(member_node));
24463 }24462 }
24464 it_index += 1;24463 it_index += 1;
24465 },24464 },
src/Zir.zig+5-5
...@@ -2427,7 +2427,7 @@ pub const Inst = struct {...@@ -2427,7 +2427,7 @@ pub const Inst = struct {
2427 operand: Ref,2427 operand: Ref,
24282428
2429 pub fn src(self: @This()) LazySrcLoc {2429 pub fn src(self: @This()) LazySrcLoc {
2430 return .{ .node_offset = self.src_node };2430 return LazySrcLoc.nodeOffset(self.src_node);
2431 }2431 }
2432 },2432 },
2433 /// Used for unary operators, with a token source location.2433 /// Used for unary operators, with a token source location.
...@@ -2450,7 +2450,7 @@ pub const Inst = struct {...@@ -2450,7 +2450,7 @@ pub const Inst = struct {
2450 payload_index: u32,2450 payload_index: u32,
24512451
2452 pub fn src(self: @This()) LazySrcLoc {2452 pub fn src(self: @This()) LazySrcLoc {
2453 return .{ .node_offset = self.src_node };2453 return LazySrcLoc.nodeOffset(self.src_node);
2454 }2454 }
2455 },2455 },
2456 pl_tok: struct {2456 pl_tok: struct {
...@@ -2526,7 +2526,7 @@ pub const Inst = struct {...@@ -2526,7 +2526,7 @@ pub const Inst = struct {
2526 bit_count: u16,2526 bit_count: u16,
25272527
2528 pub fn src(self: @This()) LazySrcLoc {2528 pub fn src(self: @This()) LazySrcLoc {
2529 return .{ .node_offset = self.src_node };2529 return LazySrcLoc.nodeOffset(self.src_node);
2530 }2530 }
2531 },2531 },
2532 bool_br: struct {2532 bool_br: struct {
...@@ -2545,7 +2545,7 @@ pub const Inst = struct {...@@ -2545,7 +2545,7 @@ pub const Inst = struct {
2545 force_comptime: bool,2545 force_comptime: bool,
25462546
2547 pub fn src(self: @This()) LazySrcLoc {2547 pub fn src(self: @This()) LazySrcLoc {
2548 return .{ .node_offset = self.src_node };2548 return LazySrcLoc.nodeOffset(self.src_node);
2549 }2549 }
2550 },2550 },
2551 @"break": struct {2551 @"break": struct {
...@@ -2566,7 +2566,7 @@ pub const Inst = struct {...@@ -2566,7 +2566,7 @@ pub const Inst = struct {
2566 inst: Index,2566 inst: Index,
25672567
2568 pub fn src(self: @This()) LazySrcLoc {2568 pub fn src(self: @This()) LazySrcLoc {
2569 return .{ .node_offset = self.src_node };2569 return LazySrcLoc.nodeOffset(self.src_node);
2570 }2570 }
2571 },2571 },
2572 str_op: struct {2572 str_op: struct {
src/arch/wasm/CodeGen.zig+1-1
...@@ -622,7 +622,7 @@ pub fn deinit(self: *Self) void {...@@ -622,7 +622,7 @@ pub fn deinit(self: *Self) void {
622622
623/// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig623/// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig
624fn fail(self: *Self, comptime fmt: []const u8, args: anytype) InnerError {624fn fail(self: *Self, comptime fmt: []const u8, args: anytype) InnerError {
625 const src: LazySrcLoc = .{ .node_offset = 0 };625 const src = LazySrcLoc.nodeOffset(0);
626 const src_loc = src.toSrcLoc(self.decl);626 const src_loc = src.toSrcLoc(self.decl);
627 self.err_msg = try Module.ErrorMsg.create(self.gpa, src_loc, fmt, args);627 self.err_msg = try Module.ErrorMsg.create(self.gpa, src_loc, fmt, args);
628 return error.CodegenFail;628 return error.CodegenFail;
src/codegen/c.zig+1-1
...@@ -363,7 +363,7 @@ pub const DeclGen = struct {...@@ -363,7 +363,7 @@ pub const DeclGen = struct {
363363
364 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {364 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
365 @setCold(true);365 @setCold(true);
366 const src: LazySrcLoc = .{ .node_offset = 0 };366 const src = LazySrcLoc.nodeOffset(0);
367 const src_loc = src.toSrcLoc(dg.decl);367 const src_loc = src.toSrcLoc(dg.decl);
368 dg.error_msg = try Module.ErrorMsg.create(dg.module.gpa, src_loc, format, args);368 dg.error_msg = try Module.ErrorMsg.create(dg.module.gpa, src_loc, format, args);
369 return error.AnalysisFail;369 return error.AnalysisFail;
src/codegen/llvm.zig+1-1
...@@ -2163,7 +2163,7 @@ pub const DeclGen = struct {...@@ -2163,7 +2163,7 @@ pub const DeclGen = struct {
2163 fn todo(self: *DeclGen, comptime format: []const u8, args: anytype) Error {2163 fn todo(self: *DeclGen, comptime format: []const u8, args: anytype) Error {
2164 @setCold(true);2164 @setCold(true);
2165 assert(self.err_msg == null);2165 assert(self.err_msg == null);
2166 const src_loc = @as(LazySrcLoc, .{ .node_offset = 0 }).toSrcLoc(self.decl);2166 const src_loc = LazySrcLoc.nodeOffset(0).toSrcLoc(self.decl);
2167 self.err_msg = try Module.ErrorMsg.create(self.gpa, src_loc, "TODO (LLVM): " ++ format, args);2167 self.err_msg = try Module.ErrorMsg.create(self.gpa, src_loc, "TODO (LLVM): " ++ format, args);
2168 return error.CodegenFail;2168 return error.CodegenFail;
2169 }2169 }
src/codegen/spirv.zig+2-2
...@@ -184,7 +184,7 @@ pub const DeclGen = struct {...@@ -184,7 +184,7 @@ pub const DeclGen = struct {
184184
185 fn fail(self: *DeclGen, comptime format: []const u8, args: anytype) Error {185 fn fail(self: *DeclGen, comptime format: []const u8, args: anytype) Error {
186 @setCold(true);186 @setCold(true);
187 const src: LazySrcLoc = .{ .node_offset = 0 };187 const src = LazySrcLoc.nodeOffset(0);
188 const src_loc = src.toSrcLoc(self.decl);188 const src_loc = src.toSrcLoc(self.decl);
189 assert(self.error_msg == null);189 assert(self.error_msg == null);
190 self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, format, args);190 self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, format, args);
...@@ -193,7 +193,7 @@ pub const DeclGen = struct {...@@ -193,7 +193,7 @@ pub const DeclGen = struct {
193193
194 fn todo(self: *DeclGen, comptime format: []const u8, args: anytype) Error {194 fn todo(self: *DeclGen, comptime format: []const u8, args: anytype) Error {
195 @setCold(true);195 @setCold(true);
196 const src: LazySrcLoc = .{ .node_offset = 0 };196 const src = LazySrcLoc.nodeOffset(0);
197 const src_loc = src.toSrcLoc(self.decl);197 const src_loc = src.toSrcLoc(self.decl);
198 assert(self.error_msg == null);198 assert(self.error_msg == null);
199 self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, "TODO (SPIR-V): " ++ format, args);199 self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, "TODO (SPIR-V): " ++ format, args);
src/config.zig.in+1
...@@ -8,6 +8,7 @@ pub const semver = @import("std").SemanticVersion.parse(version) catch unreachab...@@ -8,6 +8,7 @@ pub const semver = @import("std").SemanticVersion.parse(version) catch unreachab
8pub const enable_logging: bool = @ZIG_ENABLE_LOGGING_BOOL@;8pub const enable_logging: bool = @ZIG_ENABLE_LOGGING_BOOL@;
9pub const enable_link_snapshots: bool = false;9pub const enable_link_snapshots: bool = false;
10pub const enable_tracy = false;10pub const enable_tracy = false;
11pub const value_tracing = false;
11pub const is_stage1 = true;12pub const is_stage1 = true;
12pub const skip_non_native = false;13pub const skip_non_native = false;
13pub const omit_stage2: bool = @ZIG_OMIT_STAGE2_BOOL@;14pub const omit_stage2: bool = @ZIG_OMIT_STAGE2_BOOL@;
src/print_zir.zig+10-10
...@@ -497,7 +497,7 @@ const Writer = struct {...@@ -497,7 +497,7 @@ const Writer = struct {
497 .wasm_memory_size,497 .wasm_memory_size,
498 => {498 => {
499 const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;499 const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
500 const src: LazySrcLoc = .{ .node_offset = inst_data.node };500 const src = LazySrcLoc.nodeOffset(inst_data.node);
501 try self.writeInstRef(stream, inst_data.operand);501 try self.writeInstRef(stream, inst_data.operand);
502 try stream.writeAll(")) ");502 try stream.writeAll(")) ");
503 try self.writeSrc(stream, src);503 try self.writeSrc(stream, src);
...@@ -510,7 +510,7 @@ const Writer = struct {...@@ -510,7 +510,7 @@ const Writer = struct {
510 .prefetch,510 .prefetch,
511 => {511 => {
512 const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;512 const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
513 const src: LazySrcLoc = .{ .node_offset = inst_data.node };513 const src = LazySrcLoc.nodeOffset(inst_data.node);
514 try self.writeInstRef(stream, inst_data.lhs);514 try self.writeInstRef(stream, inst_data.lhs);
515 try stream.writeAll(", ");515 try stream.writeAll(", ");
516 try self.writeInstRef(stream, inst_data.rhs);516 try self.writeInstRef(stream, inst_data.rhs);
...@@ -520,7 +520,7 @@ const Writer = struct {...@@ -520,7 +520,7 @@ const Writer = struct {
520520
521 .field_call_bind_named => {521 .field_call_bind_named => {
522 const extra = self.code.extraData(Zir.Inst.FieldNamedNode, extended.operand).data;522 const extra = self.code.extraData(Zir.Inst.FieldNamedNode, extended.operand).data;
523 const src: LazySrcLoc = .{ .node_offset = extra.node };523 const src = LazySrcLoc.nodeOffset(extra.node);
524 try self.writeInstRef(stream, extra.lhs);524 try self.writeInstRef(stream, extra.lhs);
525 try stream.writeAll(", ");525 try stream.writeAll(", ");
526 try self.writeInstRef(stream, extra.field_name);526 try self.writeInstRef(stream, extra.field_name);
...@@ -531,7 +531,7 @@ const Writer = struct {...@@ -531,7 +531,7 @@ const Writer = struct {
531 }531 }
532532
533 fn writeExtNode(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {533 fn writeExtNode(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
534 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };534 const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand));
535 try stream.writeAll(")) ");535 try stream.writeAll(")) ");
536 try self.writeSrc(stream, src);536 try self.writeSrc(stream, src);
537 }537 }
...@@ -1050,7 +1050,7 @@ const Writer = struct {...@@ -1050,7 +1050,7 @@ const Writer = struct {
10501050
1051 fn writeNodeMultiOp(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {1051 fn writeNodeMultiOp(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
1052 const extra = self.code.extraData(Zir.Inst.NodeMultiOp, extended.operand);1052 const extra = self.code.extraData(Zir.Inst.NodeMultiOp, extended.operand);
1053 const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };1053 const src = LazySrcLoc.nodeOffset(extra.data.src_node);
1054 const operands = self.code.refSlice(extra.end, extended.small);1054 const operands = self.code.refSlice(extra.end, extended.small);
10551055
1056 for (operands) |operand, i| {1056 for (operands) |operand, i| {
...@@ -1074,7 +1074,7 @@ const Writer = struct {...@@ -1074,7 +1074,7 @@ const Writer = struct {
10741074
1075 fn writeAsm(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {1075 fn writeAsm(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
1076 const extra = self.code.extraData(Zir.Inst.Asm, extended.operand);1076 const extra = self.code.extraData(Zir.Inst.Asm, extended.operand);
1077 const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };1077 const src = LazySrcLoc.nodeOffset(extra.data.src_node);
1078 const outputs_len = @truncate(u5, extended.small);1078 const outputs_len = @truncate(u5, extended.small);
1079 const inputs_len = @truncate(u5, extended.small >> 5);1079 const inputs_len = @truncate(u5, extended.small >> 5);
1080 const clobbers_len = @truncate(u5, extended.small >> 10);1080 const clobbers_len = @truncate(u5, extended.small >> 10);
...@@ -1145,7 +1145,7 @@ const Writer = struct {...@@ -1145,7 +1145,7 @@ const Writer = struct {
11451145
1146 fn writeOverflowArithmetic(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {1146 fn writeOverflowArithmetic(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
1147 const extra = self.code.extraData(Zir.Inst.OverflowArithmetic, extended.operand).data;1147 const extra = self.code.extraData(Zir.Inst.OverflowArithmetic, extended.operand).data;
1148 const src: LazySrcLoc = .{ .node_offset = extra.node };1148 const src = LazySrcLoc.nodeOffset(extra.node);
11491149
1150 try self.writeInstRef(stream, extra.lhs);1150 try self.writeInstRef(stream, extra.lhs);
1151 try stream.writeAll(", ");1151 try stream.writeAll(", ");
...@@ -1898,7 +1898,7 @@ const Writer = struct {...@@ -1898,7 +1898,7 @@ const Writer = struct {
1898 inst: Zir.Inst.Index,1898 inst: Zir.Inst.Index,
1899 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {1899 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {
1900 const src_node = self.code.instructions.items(.data)[inst].node;1900 const src_node = self.code.instructions.items(.data)[inst].node;
1901 const src: LazySrcLoc = .{ .node_offset = src_node };1901 const src = LazySrcLoc.nodeOffset(src_node);
1902 try stream.writeAll(") ");1902 try stream.writeAll(") ");
1903 try self.writeSrc(stream, src);1903 try self.writeSrc(stream, src);
1904 }1904 }
...@@ -2117,7 +2117,7 @@ const Writer = struct {...@@ -2117,7 +2117,7 @@ const Writer = struct {
2117 fn writeAllocExtended(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {2117 fn writeAllocExtended(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
2118 const extra = self.code.extraData(Zir.Inst.AllocExtended, extended.operand);2118 const extra = self.code.extraData(Zir.Inst.AllocExtended, extended.operand);
2119 const small = @bitCast(Zir.Inst.AllocExtended.Small, extended.small);2119 const small = @bitCast(Zir.Inst.AllocExtended.Small, extended.small);
2120 const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };2120 const src = LazySrcLoc.nodeOffset(extra.data.src_node);
21212121
2122 var extra_index: usize = extra.end;2122 var extra_index: usize = extra.end;
2123 const type_inst: Zir.Inst.Ref = if (!small.has_type) .none else blk: {2123 const type_inst: Zir.Inst.Ref = if (!small.has_type) .none else blk: {
...@@ -2351,7 +2351,7 @@ const Writer = struct {...@@ -2351,7 +2351,7 @@ const Writer = struct {
23512351
2352 fn writeSrcNode(self: *Writer, stream: anytype, src_node: ?i32) !void {2352 fn writeSrcNode(self: *Writer, stream: anytype, src_node: ?i32) !void {
2353 const node_offset = src_node orelse return;2353 const node_offset = src_node orelse return;
2354 const src: LazySrcLoc = .{ .node_offset = node_offset };2354 const src = LazySrcLoc.nodeOffset(node_offset);
2355 try stream.writeAll(" ");2355 try stream.writeAll(" ");
2356 return self.writeSrc(stream, src);2356 return self.writeSrc(stream, src);
2357 }2357 }
src/test.zig+36-7
...@@ -61,10 +61,12 @@ const ErrorMsg = union(enum) {...@@ -61,10 +61,12 @@ const ErrorMsg = union(enum) {
61 // this is a workaround for stage1 compiler bug I ran into when making it ?u3261 // this is a workaround for stage1 compiler bug I ran into when making it ?u32
62 column: u32,62 column: u32,
63 kind: Kind,63 kind: Kind,
64 count: u32,
64 },65 },
65 plain: struct {66 plain: struct {
66 msg: []const u8,67 msg: []const u8,
67 kind: Kind,68 kind: Kind,
69 count: u32,
68 },70 },
6971
70 const Kind = enum {72 const Kind = enum {
...@@ -81,12 +83,14 @@ const ErrorMsg = union(enum) {...@@ -81,12 +83,14 @@ const ErrorMsg = union(enum) {
81 .line = @intCast(u32, src.line),83 .line = @intCast(u32, src.line),
82 .column = @intCast(u32, src.column),84 .column = @intCast(u32, src.column),
83 .kind = kind,85 .kind = kind,
86 .count = src.count,
84 },87 },
85 },88 },
86 .plain => |plain| return .{89 .plain => |plain| return .{
87 .plain = .{90 .plain = .{
88 .msg = plain.msg,91 .msg = plain.msg,
89 .kind = kind,92 .kind = kind,
93 .count = plain.count,
90 },94 },
91 },95 },
92 }96 }
...@@ -118,10 +122,16 @@ const ErrorMsg = union(enum) {...@@ -118,10 +122,16 @@ const ErrorMsg = union(enum) {
118 try writer.writeAll("?: ");122 try writer.writeAll("?: ");
119 }123 }
120 }124 }
121 return writer.print("{s}: {s}", .{ @tagName(src.kind), src.msg });125 try writer.print("{s}: {s}", .{ @tagName(src.kind), src.msg });
126 if (src.count != 1) {
127 try writer.print(" ({d} times)", .{src.count});
128 }
122 },129 },
123 .plain => |plain| {130 .plain => |plain| {
124 return writer.print("{s}: {s}", .{ @tagName(plain.kind), plain.msg });131 try writer.print("{s}: {s}", .{ @tagName(plain.kind), plain.msg });
132 if (plain.count != 1) {
133 try writer.print(" ({d} times)", .{plain.count});
134 }
125 },135 },
126 }136 }
127 }137 }
...@@ -647,12 +657,20 @@ pub const TestContext = struct {...@@ -647,12 +657,20 @@ pub const TestContext = struct {
647 for (errors) |err_msg_line, i| {657 for (errors) |err_msg_line, i| {
648 if (std.mem.startsWith(u8, err_msg_line, "error: ")) {658 if (std.mem.startsWith(u8, err_msg_line, "error: ")) {
649 array[i] = .{659 array[i] = .{
650 .plain = .{ .msg = err_msg_line["error: ".len..], .kind = .@"error" },660 .plain = .{
661 .msg = err_msg_line["error: ".len..],
662 .kind = .@"error",
663 .count = 1,
664 },
651 };665 };
652 continue;666 continue;
653 } else if (std.mem.startsWith(u8, err_msg_line, "note: ")) {667 } else if (std.mem.startsWith(u8, err_msg_line, "note: ")) {
654 array[i] = .{668 array[i] = .{
655 .plain = .{ .msg = err_msg_line["note: ".len..], .kind = .note },669 .plain = .{
670 .msg = err_msg_line["note: ".len..],
671 .kind = .note,
672 .count = 1,
673 },
656 };674 };
657 continue;675 continue;
658 }676 }
...@@ -662,7 +680,7 @@ pub const TestContext = struct {...@@ -662,7 +680,7 @@ pub const TestContext = struct {
662 const line_text = it.next() orelse @panic("missing line");680 const line_text = it.next() orelse @panic("missing line");
663 const col_text = it.next() orelse @panic("missing column");681 const col_text = it.next() orelse @panic("missing column");
664 const kind_text = it.next() orelse @panic("missing 'error'/'note'");682 const kind_text = it.next() orelse @panic("missing 'error'/'note'");
665 const msg = it.rest()[1..]; // skip over the space at end of "error: "683 var msg = it.rest()[1..]; // skip over the space at end of "error: "
666684
667 const line: ?u32 = if (std.mem.eql(u8, line_text, "?"))685 const line: ?u32 = if (std.mem.eql(u8, line_text, "?"))
668 null686 null
...@@ -695,6 +713,14 @@ pub const TestContext = struct {...@@ -695,6 +713,14 @@ pub const TestContext = struct {
695 break :blk n - 1;713 break :blk n - 1;
696 } else std.math.maxInt(u32);714 } else std.math.maxInt(u32);
697715
716 const suffix = " times)";
717 const count = if (std.mem.endsWith(u8, msg, suffix)) count: {
718 const lparen = std.mem.lastIndexOfScalar(u8, msg, '(').?;
719 const count = std.fmt.parseInt(u32, msg[lparen + 1 .. msg.len - suffix.len], 10) catch @panic("bad error note count number");
720 msg = msg[0 .. lparen - 1];
721 break :count count;
722 } else 1;
723
698 array[i] = .{724 array[i] = .{
699 .src = .{725 .src = .{
700 .src_path = src_path,726 .src_path = src_path,
...@@ -702,6 +728,7 @@ pub const TestContext = struct {...@@ -702,6 +728,7 @@ pub const TestContext = struct {
702 .line = line_0based,728 .line = line_0based,
703 .column = column_0based,729 .column = column_0based,
704 .kind = kind,730 .kind = kind,
731 .count = count,
705 },732 },
706 };733 };
707 }734 }
...@@ -1606,7 +1633,8 @@ pub const TestContext = struct {...@@ -1606,7 +1633,8 @@ pub const TestContext = struct {
1606 (case_msg.src.column == std.math.maxInt(u32) or1633 (case_msg.src.column == std.math.maxInt(u32) or
1607 actual_msg.column == case_msg.src.column) and1634 actual_msg.column == case_msg.src.column) and
1608 std.mem.eql(u8, expected_msg, actual_msg.msg) and1635 std.mem.eql(u8, expected_msg, actual_msg.msg) and
1609 case_msg.src.kind == .@"error")1636 case_msg.src.kind == .@"error" and
1637 actual_msg.count == case_msg.src.count)
1610 {1638 {
1611 handled_errors[i] = true;1639 handled_errors[i] = true;
1612 break;1640 break;
...@@ -1616,7 +1644,8 @@ pub const TestContext = struct {...@@ -1616,7 +1644,8 @@ pub const TestContext = struct {
1616 if (ex_tag != .plain) continue;1644 if (ex_tag != .plain) continue;
16171645
1618 if (std.mem.eql(u8, case_msg.plain.msg, plain.msg) and1646 if (std.mem.eql(u8, case_msg.plain.msg, plain.msg) and
1619 case_msg.plain.kind == .@"error")1647 case_msg.plain.kind == .@"error" and
1648 case_msg.plain.count == plain.count)
1620 {1649 {
1621 handled_errors[i] = true;1650 handled_errors[i] = true;
1622 break;1651 break;
test/behavior/bugs/920.zig+17-3
...@@ -1,14 +1,24 @@...@@ -1,14 +1,24 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const Random = std.rand.Random;3const Random = std.rand.Random;
34
5const zeroCaseFn = switch (builtin.zig_backend) {
6 .stage1 => fn (*Random, f64) f64,
7 else => *const fn (*Random, f64) f64,
8};
9const pdfFn = switch (builtin.zig_backend) {
10 .stage1 => fn (f64) f64,
11 else => *const fn (f64) f64,
12};
13
4const ZigTable = struct {14const ZigTable = struct {
5 r: f64,15 r: f64,
6 x: [257]f64,16 x: [257]f64,
7 f: [257]f64,17 f: [257]f64,
818
9 pdf: fn (f64) f64,19 pdf: pdfFn,
10 is_symmetric: bool,20 is_symmetric: bool,
11 zero_case: fn (*Random, f64) f64,21 zero_case: zeroCaseFn,
12};22};
1323
14fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, comptime f: fn (f64) f64, comptime f_inv: fn (f64) f64, comptime zero_case: fn (*Random, f64) f64) ZigTable {24fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, comptime f: fn (f64) f64, comptime f_inv: fn (f64) f64, comptime zero_case: fn (*Random, f64) f64) ZigTable {
...@@ -56,7 +66,11 @@ const NormalDist = blk: {...@@ -56,7 +66,11 @@ const NormalDist = blk: {
56};66};
5767
58test "bug 920 fixed" {68test "bug 920 fixed" {
59 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO69 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
70 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
71 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
72 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
73 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
6074
61 const NormalDist1 = blk: {75 const NormalDist1 = blk: {
62 break :blk ZigTableGen(true, norm_r, norm_v, norm_f, norm_f_inv, norm_zero_case);76 break :blk ZigTableGen(true, norm_r, norm_v, norm_f, norm_f_inv, norm_zero_case);
test/cases/recursive_inline_function.1.zig+3
...@@ -14,3 +14,6 @@ inline fn fibonacci(n: usize) usize {...@@ -14,3 +14,6 @@ inline fn fibonacci(n: usize) usize {
14// error14// error
15//15//
16// :11:21: error: evaluation exceeded 1000 backwards branches16// :11:21: error: evaluation exceeded 1000 backwards branches
17// :11:40: note: called from here (6 times)
18// :11:21: note: called from here (495 times)
19// :5:24: note: called from here
test/stage2/cbe.zig-24
...@@ -233,30 +233,6 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -233,30 +233,6 @@ pub fn addCases(ctx: *TestContext) !void {
233 \\}233 \\}
234 , "");234 , "");
235 }235 }
236 // This will make a pretty deep call stack, so this test can only be enabled
237 // on hosts where Zig's linking strategy can honor the 16 MiB (default) we
238 // link the self-hosted compiler with.
239 const host_supports_custom_stack_size = @import("builtin").target.os.tag == .linux;
240 if (host_supports_custom_stack_size) {
241 var case = ctx.exeFromCompiledC("@setEvalBranchQuota", .{});
242
243 // TODO when adding result location support to function calls, revisit this test
244 // case. It can go back to what it was before, with `y` being comptime known.
245 // Because the ret_ptr will passed in with the inline fn call, and there will
246 // only be 1 store to it, and it will be comptime known.
247 case.addCompareOutput(
248 \\pub export fn main() i32 {
249 \\ @setEvalBranchQuota(1001);
250 \\ const y = rec(1001);
251 \\ return y - 1;
252 \\}
253 \\
254 \\inline fn rec(n: i32) i32 {
255 \\ if (n <= 1) return n;
256 \\ return rec(n - 1);
257 \\}
258 , "");
259 }
260 {236 {
261 var case = ctx.exeFromCompiledC("control flow", .{});237 var case = ctx.exeFromCompiledC("control flow", .{});
262238