authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-14 21:26:01+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-14 22:18:58+03:00
logb5a838247bd7d66037ba48378c34ba4460747deb
tree353926c424c6d6d8153e23b50862cfb9c3a7088b
parenta4559271501670b39305fc3575ae8d87fa03d35e

stage2: point to error location using spans


4 files changed, 128 insertions(+), 150 deletions(-)

src/Compilation.zig+31-28
......@@ -338,7 +338,7 @@ pub const AllErrors = struct {
338338 src_path: []const u8,
339339 line: u32,
340340 column: u32,
341 byte_offset: u32,
341 span: Module.SrcLoc.Span,
342342 /// Usually one, but incremented for redundant messages.
343343 count: u32 = 1,
344344 /// Does not include the trailing newline.
......@@ -429,7 +429,10 @@ pub const AllErrors = struct {
429429 try stderr.writeByte('\n');
430430 try stderr.writeByteNTimes(' ', src.column);
431431 ttyconf.setColor(stderr, .Green);
432 try stderr.writeAll("^\n");
432 try stderr.writeByte('^');
433 // TODO basic unicode code point monospace width
434 try stderr.writeByteNTimes('~', src.span.end - src.span.start - 1);
435 try stderr.writeByte('\n');
433436 ttyconf.setColor(stderr, .Reset);
434437 }
435438 }
......@@ -469,7 +472,8 @@ pub const AllErrors = struct {
469472 hasher.update(src.src_path);
470473 std.hash.autoHash(&hasher, src.line);
471474 std.hash.autoHash(&hasher, src.column);
472 std.hash.autoHash(&hasher, src.byte_offset);
475 std.hash.autoHash(&hasher, src.span.start);
476 std.hash.autoHash(&hasher, src.span.end);
473477 },
474478 .plain => |plain| {
475479 hasher.update(plain.msg);
......@@ -488,7 +492,8 @@ pub const AllErrors = struct {
488492 mem.eql(u8, a_src.src_path, b_src.src_path) and
489493 a_src.line == b_src.line and
490494 a_src.column == b_src.column and
491 a_src.byte_offset == b_src.byte_offset;
495 a_src.span.start == b_src.span.start and
496 a_src.span.end == b_src.span.end;
492497 },
493498 .plain => return false,
494499 },
......@@ -527,20 +532,20 @@ pub const AllErrors = struct {
527532 std.hash_map.default_max_load_percentage,
528533 ).init(allocator);
529534 const err_source = try module_err_msg.src_loc.file_scope.getSource(module.gpa);
530 const err_byte_offset = try module_err_msg.src_loc.byteOffset(module.gpa);
531 const err_loc = std.zig.findLineColumn(err_source.bytes, err_byte_offset);
535 const err_span = try module_err_msg.src_loc.span(module.gpa);
536 const err_loc = std.zig.findLineColumn(err_source.bytes, err_span.start);
532537
533538 for (module_err_msg.notes) |module_note| {
534539 const source = try module_note.src_loc.file_scope.getSource(module.gpa);
535 const byte_offset = try module_note.src_loc.byteOffset(module.gpa);
536 const loc = std.zig.findLineColumn(source.bytes, byte_offset);
540 const span = try module_note.src_loc.span(module.gpa);
541 const loc = std.zig.findLineColumn(source.bytes, span.start);
537542 const file_path = try module_note.src_loc.file_scope.fullPath(allocator);
538543 const note = &notes_buf[note_i];
539544 note.* = .{
540545 .src = .{
541546 .src_path = file_path,
542547 .msg = try allocator.dupe(u8, module_note.msg),
543 .byte_offset = byte_offset,
548 .span = span,
544549 .line = @intCast(u32, loc.line),
545550 .column = @intCast(u32, loc.column),
546551 .source_line = if (err_loc.eql(loc)) null else try allocator.dupe(u8, loc.source_line),
......@@ -566,7 +571,7 @@ pub const AllErrors = struct {
566571 .src = .{
567572 .src_path = file_path,
568573 .msg = try allocator.dupe(u8, module_err_msg.msg),
569 .byte_offset = err_byte_offset,
574 .span = err_span,
570575 .line = @intCast(u32, err_loc.line),
571576 .column = @intCast(u32, err_loc.column),
572577 .notes = notes_buf[0..note_i],
......@@ -593,16 +598,15 @@ pub const AllErrors = struct {
593598 while (item_i < items_len) : (item_i += 1) {
594599 const item = file.zir.extraData(Zir.Inst.CompileErrors.Item, extra_index);
595600 extra_index = item.end;
596 const err_byte_offset = blk: {
597 const token_starts = file.tree.tokens.items(.start);
601 const err_span = blk: {
598602 if (item.data.node != 0) {
599 const main_tokens = file.tree.nodes.items(.main_token);
600 const main_token = main_tokens[item.data.node];
601 break :blk token_starts[main_token];
603 break :blk Module.SrcLoc.nodeToSpan(&file.tree, item.data.node);
602604 }
603 break :blk token_starts[item.data.token] + item.data.byte_offset;
605 const token_starts = file.tree.tokens.items(.start);
606 const start = token_starts[item.data.token] + item.data.byte_offset;
607 break :blk Module.SrcLoc.Span{ .start = start, .end = start + 1 };
604608 };
605 const err_loc = std.zig.findLineColumn(file.source, err_byte_offset);
609 const err_loc = std.zig.findLineColumn(file.source, err_span.start);
606610
607611 var notes: []Message = &[0]Message{};
608612 if (item.data.notes != 0) {
......@@ -612,22 +616,21 @@ pub const AllErrors = struct {
612616 for (notes) |*note, i| {
613617 const note_item = file.zir.extraData(Zir.Inst.CompileErrors.Item, body[i]);
614618 const msg = file.zir.nullTerminatedString(note_item.data.msg);
615 const byte_offset = blk: {
616 const token_starts = file.tree.tokens.items(.start);
619 const span = blk: {
617620 if (note_item.data.node != 0) {
618 const main_tokens = file.tree.nodes.items(.main_token);
619 const main_token = main_tokens[note_item.data.node];
620 break :blk token_starts[main_token];
621 break :blk Module.SrcLoc.nodeToSpan(&file.tree, note_item.data.node);
621622 }
622 break :blk token_starts[note_item.data.token] + note_item.data.byte_offset;
623 const token_starts = file.tree.tokens.items(.start);
624 const start = token_starts[note_item.data.token] + note_item.data.byte_offset;
625 break :blk Module.SrcLoc.Span{ .start = start, .end = start + 1 };
623626 };
624 const loc = std.zig.findLineColumn(file.source, byte_offset);
627 const loc = std.zig.findLineColumn(file.source, span.start);
625628
626629 note.* = .{
627630 .src = .{
628631 .src_path = try file.fullPath(arena),
629632 .msg = try arena.dupe(u8, msg),
630 .byte_offset = byte_offset,
633 .span = span,
631634 .line = @intCast(u32, loc.line),
632635 .column = @intCast(u32, loc.column),
633636 .notes = &.{}, // TODO rework this function to be recursive
......@@ -642,7 +645,7 @@ pub const AllErrors = struct {
642645 .src = .{
643646 .src_path = try file.fullPath(arena),
644647 .msg = try arena.dupe(u8, msg),
645 .byte_offset = err_byte_offset,
648 .span = err_span,
646649 .line = @intCast(u32, err_loc.line),
647650 .column = @intCast(u32, err_loc.column),
648651 .notes = notes,
......@@ -688,7 +691,7 @@ pub const AllErrors = struct {
688691 .src_path = try arena.dupe(u8, src.src_path),
689692 .line = src.line,
690693 .column = src.column,
691 .byte_offset = src.byte_offset,
694 .span = src.span,
692695 .source_line = if (src.source_line) |s| try arena.dupe(u8, s) else null,
693696 .notes = try dupeList(src.notes, arena),
694697 } },
......@@ -2662,7 +2665,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
26622665 .msg = try std.fmt.allocPrint(arena_allocator, "unable to build C object: {s}", .{
26632666 err_msg.msg,
26642667 }),
2665 .byte_offset = 0,
2668 .span = .{ .start = 0, .end = 1 },
26662669 .line = err_msg.line,
26672670 .column = err_msg.column,
26682671 .source_line = null, // TODO
src/Module.zig+86-115
......@@ -2082,60 +2082,62 @@ pub const SrcLoc = struct {
20822082 return @bitCast(Ast.Node.Index, offset + @bitCast(i32, src_loc.parent_decl_node));
20832083 }
20842084
2085 pub fn byteOffset(src_loc: SrcLoc, gpa: Allocator) !u32 {
2085 pub const Span = struct {
2086 start: u32,
2087 end: u32,
2088 };
2089
2090 pub fn span(src_loc: SrcLoc, gpa: Allocator) !Span {
20862091 switch (src_loc.lazy) {
20872092 .unneeded => unreachable,
2088 .entire_file => return 0,
2093 .entire_file => return Span{ .start = 0, .end = 1 },
20892094
2090 .byte_abs => |byte_index| return byte_index,
2095 .byte_abs => |byte_index| return Span{ .start = byte_index, .end = byte_index + 1 },
20912096
20922097 .token_abs => |tok_index| {
20932098 const tree = try src_loc.file_scope.getTree(gpa);
2094 const token_starts = tree.tokens.items(.start);
2095 return token_starts[tok_index];
2099 const start = tree.tokens.items(.start)[tok_index];
2100 const end = start + @intCast(u32, tree.tokenSlice(tok_index).len);
2101 return Span{ .start = start, .end = end };
20962102 },
20972103 .node_abs => |node| {
20982104 const tree = try src_loc.file_scope.getTree(gpa);
2099 const token_starts = tree.tokens.items(.start);
2100 const tok_index = tree.firstToken(node);
2101 return token_starts[tok_index];
2105 return nodeToSpan(tree, node);
21022106 },
21032107 .byte_offset => |byte_off| {
21042108 const tree = try src_loc.file_scope.getTree(gpa);
2105 const token_starts = tree.tokens.items(.start);
2106 return token_starts[src_loc.declSrcToken()] + byte_off;
2109 const tok_index = src_loc.declSrcToken();
2110 const start = tree.tokens.items(.start)[tok_index] + byte_off;
2111 const end = start + @intCast(u32, tree.tokenSlice(tok_index).len);
2112 return Span{ .start = start, .end = end };
21072113 },
21082114 .token_offset => |tok_off| {
21092115 const tree = try src_loc.file_scope.getTree(gpa);
21102116 const tok_index = src_loc.declSrcToken() + tok_off;
2111 const token_starts = tree.tokens.items(.start);
2112 return token_starts[tok_index];
2117 const start = tree.tokens.items(.start)[tok_index];
2118 const end = start + @intCast(u32, tree.tokenSlice(tok_index).len);
2119 return Span{ .start = start, .end = end };
21132120 },
21142121 .node_offset => |traced_off| {
21152122 const node_off = traced_off.x;
21162123 const tree = try src_loc.file_scope.getTree(gpa);
21172124 const node = src_loc.declRelativeToNodeIndex(node_off);
21182125 assert(src_loc.file_scope.tree_loaded);
2119 const main_tokens = tree.nodes.items(.main_token);
2120 const tok_index = main_tokens[node];
2121 const token_starts = tree.tokens.items(.start);
2122 return token_starts[tok_index];
2126 return nodeToSpan(tree, node);
21232127 },
21242128 .node_offset_bin_op => |node_off| {
21252129 const tree = try src_loc.file_scope.getTree(gpa);
21262130 const node = src_loc.declRelativeToNodeIndex(node_off);
21272131 assert(src_loc.file_scope.tree_loaded);
2128 const main_tokens = tree.nodes.items(.main_token);
2129 const tok_index = main_tokens[node];
2130 const token_starts = tree.tokens.items(.start);
2131 return token_starts[tok_index];
2132 return nodeToSpan(tree, node);
21322133 },
21332134 .node_offset_back2tok => |node_off| {
21342135 const tree = try src_loc.file_scope.getTree(gpa);
21352136 const node = src_loc.declRelativeToNodeIndex(node_off);
21362137 const tok_index = tree.firstToken(node) - 2;
2137 const token_starts = tree.tokens.items(.start);
2138 return token_starts[tok_index];
2138 const start = tree.tokens.items(.start)[tok_index];
2139 const end = start + @intCast(u32, tree.tokenSlice(tok_index).len);
2140 return Span{ .start = start, .end = end };
21392141 },
21402142 .node_offset_var_decl_ty => |node_off| {
21412143 const tree = try src_loc.file_scope.getTree(gpa);
......@@ -2154,8 +2156,9 @@ pub const SrcLoc = struct {
21542156 } else blk: {
21552157 break :blk full.ast.mut_token + 1; // the name token
21562158 };
2157 const token_starts = tree.tokens.items(.start);
2158 return token_starts[tok_index];
2159 const start = tree.tokens.items(.start)[tok_index];
2160 const end = start + @intCast(u32, tree.tokenSlice(tok_index).len);
2161 return Span{ .start = start, .end = end };
21592162 },
21602163 .node_offset_builtin_call_arg0 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 0),
21612164 .node_offset_builtin_call_arg1 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 1),
......@@ -2167,10 +2170,7 @@ pub const SrcLoc = struct {
21672170 const tree = try src_loc.file_scope.getTree(gpa);
21682171 const node_datas = tree.nodes.items(.data);
21692172 const node = src_loc.declRelativeToNodeIndex(node_off);
2170 const main_tokens = tree.nodes.items(.main_token);
2171 const tok_index = main_tokens[node_datas[node].rhs];
2172 const token_starts = tree.tokens.items(.start);
2173 return token_starts[tok_index];
2173 return nodeToSpan(tree, node_datas[node].rhs);
21742174 },
21752175 .node_offset_slice_ptr,
21762176 .node_offset_slice_start,
......@@ -2187,7 +2187,7 @@ pub const SrcLoc = struct {
21872187 else => unreachable,
21882188 };
21892189 const main_tokens = tree.nodes.items(.main_token);
2190 const tok_index = main_tokens[
2190 const part_node = main_tokens[
21912191 switch (src_loc.lazy) {
21922192 .node_offset_slice_ptr => full.ast.sliced,
21932193 .node_offset_slice_start => full.ast.start,
......@@ -2196,8 +2196,7 @@ pub const SrcLoc = struct {
21962196 else => unreachable,
21972197 }
21982198 ];
2199 const token_starts = tree.tokens.items(.start);
2200 return token_starts[tok_index];
2199 return nodeToSpan(tree, part_node);
22012200 },
22022201 .node_offset_call_func => |node_off| {
22032202 const tree = try src_loc.file_scope.getTree(gpa);
......@@ -2219,10 +2218,7 @@ pub const SrcLoc = struct {
22192218
22202219 else => unreachable,
22212220 };
2222 const main_tokens = tree.nodes.items(.main_token);
2223 const tok_index = main_tokens[full.ast.fn_expr];
2224 const token_starts = tree.tokens.items(.start);
2225 return token_starts[tok_index];
2221 return nodeToSpan(tree, full.ast.fn_expr);
22262222 },
22272223 .node_offset_field_name => |node_off| {
22282224 const tree = try src_loc.file_scope.getTree(gpa);
......@@ -2233,16 +2229,14 @@ pub const SrcLoc = struct {
22332229 .field_access => node_datas[node].rhs,
22342230 else => tree.firstToken(node) - 2,
22352231 };
2236 const token_starts = tree.tokens.items(.start);
2237 return token_starts[tok_index];
2232 const start = tree.tokens.items(.start)[tok_index];
2233 const end = start + @intCast(u32, tree.tokenSlice(tok_index).len);
2234 return Span{ .start = start, .end = end };
22382235 },
22392236 .node_offset_deref_ptr => |node_off| {
22402237 const tree = try src_loc.file_scope.getTree(gpa);
2241 const node_datas = tree.nodes.items(.data);
22422238 const node = src_loc.declRelativeToNodeIndex(node_off);
2243 const tok_index = node_datas[node].lhs;
2244 const token_starts = tree.tokens.items(.start);
2245 return token_starts[tok_index];
2239 return nodeToSpan(tree, node);
22462240 },
22472241 .node_offset_asm_source => |node_off| {
22482242 const tree = try src_loc.file_scope.getTree(gpa);
......@@ -2253,10 +2247,7 @@ pub const SrcLoc = struct {
22532247 .@"asm" => tree.asmFull(node),
22542248 else => unreachable,
22552249 };
2256 const main_tokens = tree.nodes.items(.main_token);
2257 const tok_index = main_tokens[full.ast.template];
2258 const token_starts = tree.tokens.items(.start);
2259 return token_starts[tok_index];
2250 return nodeToSpan(tree, full.ast.template);
22602251 },
22612252 .node_offset_asm_ret_ty => |node_off| {
22622253 const tree = try src_loc.file_scope.getTree(gpa);
......@@ -2269,11 +2260,7 @@ pub const SrcLoc = struct {
22692260 };
22702261 const asm_output = full.outputs[0];
22712262 const node_datas = tree.nodes.items(.data);
2272 const ret_ty_node = node_datas[asm_output].lhs;
2273 const main_tokens = tree.nodes.items(.main_token);
2274 const tok_index = main_tokens[ret_ty_node];
2275 const token_starts = tree.tokens.items(.start);
2276 return token_starts[tok_index];
2263 return nodeToSpan(tree, node_datas[asm_output].lhs);
22772264 },
22782265
22792266 .node_offset_for_cond, .node_offset_if_cond => |node_off| {
......@@ -2290,41 +2277,26 @@ pub const SrcLoc = struct {
22902277 .@"for" => tree.forFull(node).ast.cond_expr,
22912278 else => unreachable,
22922279 };
2293 const main_tokens = tree.nodes.items(.main_token);
2294 const tok_index = main_tokens[src_node];
2295 const token_starts = tree.tokens.items(.start);
2296 return token_starts[tok_index];
2280 return nodeToSpan(tree, src_node);
22972281 },
22982282 .node_offset_bin_lhs => |node_off| {
22992283 const tree = try src_loc.file_scope.getTree(gpa);
23002284 const node = src_loc.declRelativeToNodeIndex(node_off);
23012285 const node_datas = tree.nodes.items(.data);
2302 const src_node = node_datas[node].lhs;
2303 const main_tokens = tree.nodes.items(.main_token);
2304 const tok_index = main_tokens[src_node];
2305 const token_starts = tree.tokens.items(.start);
2306 return token_starts[tok_index];
2286 return nodeToSpan(tree, node_datas[node].lhs);
23072287 },
23082288 .node_offset_bin_rhs => |node_off| {
23092289 const tree = try src_loc.file_scope.getTree(gpa);
23102290 const node = src_loc.declRelativeToNodeIndex(node_off);
23112291 const node_datas = tree.nodes.items(.data);
2312 const src_node = node_datas[node].rhs;
2313 const main_tokens = tree.nodes.items(.main_token);
2314 const tok_index = main_tokens[src_node];
2315 const token_starts = tree.tokens.items(.start);
2316 return token_starts[tok_index];
2292 return nodeToSpan(tree, node_datas[node].rhs);
23172293 },
23182294
23192295 .node_offset_switch_operand => |node_off| {
23202296 const tree = try src_loc.file_scope.getTree(gpa);
23212297 const node = src_loc.declRelativeToNodeIndex(node_off);
23222298 const node_datas = tree.nodes.items(.data);
2323 const src_node = node_datas[node].lhs;
2324 const main_tokens = tree.nodes.items(.main_token);
2325 const tok_index = main_tokens[src_node];
2326 const token_starts = tree.tokens.items(.start);
2327 return token_starts[tok_index];
2299 return nodeToSpan(tree, node_datas[node].lhs);
23282300 },
23292301
23302302 .node_offset_switch_special_prong => |node_off| {
......@@ -2347,9 +2319,7 @@ pub const SrcLoc = struct {
23472319 mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_"));
23482320 if (!is_special) continue;
23492321
2350 const tok_index = main_tokens[case_node];
2351 const token_starts = tree.tokens.items(.start);
2352 return token_starts[tok_index];
2322 return nodeToSpan(tree, case_node);
23532323 } else unreachable;
23542324 },
23552325
......@@ -2375,9 +2345,7 @@ pub const SrcLoc = struct {
23752345
23762346 for (case.ast.values) |item_node| {
23772347 if (node_tags[item_node] == .switch_range) {
2378 const tok_index = main_tokens[item_node];
2379 const token_starts = tree.tokens.items(.start);
2380 return token_starts[tok_index];
2348 return nodeToSpan(tree, item_node);
23812349 }
23822350 }
23832351 } else unreachable;
......@@ -2403,10 +2371,7 @@ pub const SrcLoc = struct {
24032371 },
24042372 else => unreachable,
24052373 };
2406 const main_tokens = tree.nodes.items(.main_token);
2407 const tok_index = main_tokens[full.ast.callconv_expr];
2408 const token_starts = tree.tokens.items(.start);
2409 return token_starts[tok_index];
2374 return nodeToSpan(tree, full.ast.callconv_expr);
24102375 },
24112376
24122377 .node_offset_fn_type_ret_ty => |node_off| {
......@@ -2421,21 +2386,14 @@ pub const SrcLoc = struct {
24212386 .fn_proto => tree.fnProto(node),
24222387 else => unreachable,
24232388 };
2424 const main_tokens = tree.nodes.items(.main_token);
2425 const tok_index = main_tokens[full.ast.return_type];
2426 const token_starts = tree.tokens.items(.start);
2427 return token_starts[tok_index];
2389 return nodeToSpan(tree, full.ast.return_type);
24282390 },
24292391
24302392 .node_offset_anyframe_type => |node_off| {
24312393 const tree = try src_loc.file_scope.getTree(gpa);
24322394 const node_datas = tree.nodes.items(.data);
24332395 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
2434 const node = node_datas[parent_node].rhs;
2435 const main_tokens = tree.nodes.items(.main_token);
2436 const tok_index = main_tokens[node];
2437 const token_starts = tree.tokens.items(.start);
2438 return token_starts[tok_index];
2396 return nodeToSpan(tree, node_datas[parent_node].rhs);
24392397 },
24402398
24412399 .node_offset_lib_name => |node_off| {
......@@ -2462,8 +2420,9 @@ pub const SrcLoc = struct {
24622420 else => unreachable,
24632421 };
24642422 const tok_index = full.lib_name.?;
2465 const token_starts = tree.tokens.items(.start);
2466 return token_starts[tok_index];
2423 const start = tree.tokens.items(.start)[tok_index];
2424 const end = start + @intCast(u32, tree.tokenSlice(tok_index).len);
2425 return Span{ .start = start, .end = end };
24672426 },
24682427
24692428 .node_offset_array_type_len => |node_off| {
......@@ -2476,11 +2435,7 @@ pub const SrcLoc = struct {
24762435 .array_type_sentinel => tree.arrayTypeSentinel(parent_node),
24772436 else => unreachable,
24782437 };
2479 const node = full.ast.elem_count;
2480 const main_tokens = tree.nodes.items(.main_token);
2481 const tok_index = main_tokens[node];
2482 const token_starts = tree.tokens.items(.start);
2483 return token_starts[tok_index];
2438 return nodeToSpan(tree, full.ast.elem_count);
24842439 },
24852440 .node_offset_array_type_sentinel => |node_off| {
24862441 const tree = try src_loc.file_scope.getTree(gpa);
......@@ -2492,11 +2447,7 @@ pub const SrcLoc = struct {
24922447 .array_type_sentinel => tree.arrayTypeSentinel(parent_node),
24932448 else => unreachable,
24942449 };
2495 const node = full.ast.sentinel;
2496 const main_tokens = tree.nodes.items(.main_token);
2497 const tok_index = main_tokens[node];
2498 const token_starts = tree.tokens.items(.start);
2499 return token_starts[tok_index];
2450 return nodeToSpan(tree, full.ast.sentinel);
25002451 },
25012452 .node_offset_array_type_elem => |node_off| {
25022453 const tree = try src_loc.file_scope.getTree(gpa);
......@@ -2508,21 +2459,14 @@ pub const SrcLoc = struct {
25082459 .array_type_sentinel => tree.arrayTypeSentinel(parent_node),
25092460 else => unreachable,
25102461 };
2511 const node = full.ast.elem_type;
2512 const main_tokens = tree.nodes.items(.main_token);
2513 const tok_index = main_tokens[node];
2514 const token_starts = tree.tokens.items(.start);
2515 return token_starts[tok_index];
2462 return nodeToSpan(tree, full.ast.elem_type);
25162463 },
25172464 .node_offset_un_op => |node_off| {
25182465 const tree = try src_loc.file_scope.getTree(gpa);
25192466 const node_datas = tree.nodes.items(.data);
25202467 const node = src_loc.declRelativeToNodeIndex(node_off);
25212468
2522 const main_tokens = tree.nodes.items(.main_token);
2523 const tok_index = main_tokens[node_datas[node].lhs];
2524 const token_starts = tree.tokens.items(.start);
2525 return token_starts[tok_index];
2469 return nodeToSpan(tree, node_datas[node].lhs);
25262470 },
25272471 }
25282472 }
......@@ -2532,7 +2476,7 @@ pub const SrcLoc = struct {
25322476 gpa: Allocator,
25332477 node_off: i32,
25342478 arg_index: u32,
2535 ) !u32 {
2479 ) !Span {
25362480 const tree = try src_loc.file_scope.getTree(gpa);
25372481 const node_datas = tree.nodes.items(.data);
25382482 const node_tags = tree.nodes.items(.tag);
......@@ -2546,10 +2490,33 @@ pub const SrcLoc = struct {
25462490 .builtin_call, .builtin_call_comma => tree.extra_data[node_datas[node].lhs + arg_index],
25472491 else => unreachable,
25482492 };
2549 const main_tokens = tree.nodes.items(.main_token);
2550 const tok_index = main_tokens[param];
2493 return nodeToSpan(tree, param);
2494 }
2495
2496 pub fn nodeToSpan(tree: *const Ast, node: u32) Span {
25512497 const token_starts = tree.tokens.items(.start);
2552 return token_starts[tok_index];
2498 const start = tree.firstToken(node);
2499 const end = tree.lastToken(node);
2500 if (tree.tokensOnSameLine(start, end)) {
2501 const start_off = token_starts[start];
2502 const end_off = token_starts[end] + @intCast(u32, tree.tokenSlice(end).len);
2503 return Span{ .start = start_off, .end = end_off };
2504 }
2505
2506 const main_token = tree.nodes.items(.main_token)[node];
2507 if (tree.tokensOnSameLine(start, main_token)) {
2508 const start_off = token_starts[start];
2509 const end_off = token_starts[main_token] + @intCast(u32, tree.tokenSlice(main_token).len);
2510 return Span{ .start = start_off, .end = end_off };
2511 }
2512 if (tree.tokensOnSameLine(main_token, end)) {
2513 const start_off = token_starts[main_token];
2514 const end_off = token_starts[end] + @intCast(u32, tree.tokenSlice(end).len);
2515 return Span{ .start = start_off, .end = end_off };
2516 }
2517 const start_off = token_starts[main_token];
2518 const end_off = token_starts[main_token] + @intCast(u32, tree.tokenSlice(main_token).len);
2519 return Span{ .start = start_off, .end = end_off };
25532520 }
25542521};
25552522
......@@ -3313,7 +3280,11 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
33133280 .src_loc = .{
33143281 .file_scope = file,
33153282 .parent_decl_node = 0,
3316 .lazy = .{ .byte_abs = token_starts[parse_err.token] + extra_offset },
3283 .lazy = if (extra_offset == 0) .{
3284 .token_abs = parse_err.token,
3285 } else .{
3286 .byte_abs = token_starts[parse_err.token],
3287 },
33173288 },
33183289 .msg = msg.toOwnedSlice(),
33193290 };
......@@ -3336,7 +3307,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
33363307 .src_loc = .{
33373308 .file_scope = file,
33383309 .parent_decl_node = 0,
3339 .lazy = .{ .byte_abs = token_starts[note.token] },
3310 .lazy = .{ .token_abs = note.token },
33403311 },
33413312 .msg = msg.toOwnedSlice(),
33423313 };
src/main.zig+5-3
......@@ -4381,7 +4381,7 @@ fn printErrsMsgToStdErr(
43814381 .msg = try std.fmt.allocPrint(arena, "invalid byte: '{'}'", .{
43824382 std.zig.fmtEscapes(tree.source[byte_offset..][0..1]),
43834383 }),
4384 .byte_offset = byte_offset,
4384 .span = .{ .start = byte_offset, .end = byte_offset + 1 },
43854385 .line = @intCast(u32, start_loc.line),
43864386 .column = @intCast(u32, start_loc.column) + bad_off,
43874387 .source_line = source_line,
......@@ -4396,11 +4396,12 @@ fn printErrsMsgToStdErr(
43964396 text_buf.items.len = 0;
43974397 try tree.renderError(note, writer);
43984398 const note_loc = tree.tokenLocation(0, note.token);
4399 const byte_offset = @intCast(u32, note_loc.line_start);
43994400 notes_buffer[notes_len] = .{
44004401 .src = .{
44014402 .src_path = path,
44024403 .msg = try arena.dupe(u8, text_buf.items),
4403 .byte_offset = @intCast(u32, note_loc.line_start),
4404 .span = .{ .start = byte_offset, .end = byte_offset + @intCast(u32, tree.tokenSlice(note.token).len) },
44044405 .line = @intCast(u32, note_loc.line),
44054406 .column = @intCast(u32, note_loc.column),
44064407 .source_line = tree.source[note_loc.line_start..note_loc.line_end],
......@@ -4411,11 +4412,12 @@ fn printErrsMsgToStdErr(
44114412 }
44124413
44134414 const extra_offset = tree.errorOffset(parse_error);
4415 const byte_offset = @intCast(u32, start_loc.line_start) + extra_offset;
44144416 const message: Compilation.AllErrors.Message = .{
44154417 .src = .{
44164418 .src_path = path,
44174419 .msg = text,
4418 .byte_offset = @intCast(u32, start_loc.line_start) + extra_offset,
4420 .span = .{ .start = byte_offset, .end = byte_offset + @intCast(u32, tree.tokenSlice(lok_token).len) },
44194421 .line = @intCast(u32, start_loc.line),
44204422 .column = @intCast(u32, start_loc.column) + extra_offset,
44214423 .source_line = source_line,
src/print_zir.zig+6-4
......@@ -2381,10 +2381,12 @@ const Writer = struct {
23812381 .parent_decl_node = self.parent_decl_node,
23822382 .lazy = src,
23832383 };
2384 const abs_byte_off = src_loc.byteOffset(self.gpa) catch unreachable;
2385 const delta_line = std.zig.findLineColumn(tree.source, abs_byte_off);
2386 try stream.print("{s}:{d}:{d}", .{
2387 @tagName(src), delta_line.line + 1, delta_line.column + 1,
2384 const src_span = src_loc.span(self.gpa) catch unreachable;
2385 const start = std.zig.findLineColumn(tree.source, src_span.start);
2386 const end = std.zig.findLineColumn(tree.source, src_span.end);
2387 try stream.print("{s}:{d}:{d} to :{d}:{d}", .{
2388 @tagName(src), start.line + 1, start.column + 1,
2389 end.line + 1, end.column + 1,
23882390 });
23892391 }
23902392 }