@@ -338,7 +338,7 @@ pub const AllErrors = struct {
338
338
src_path : []const u8 ,
339
339
line : u32 ,
340
340
column : u32 ,
341
- byte_offset : u32 ,
341
+ span : Module.SrcLoc.Span ,
342
342
/// Usually one, but incremented for redundant messages.
343
343
count : u32 = 1 ,
344
344
/// Does not include the trailing newline.
@@ -427,9 +427,16 @@ pub const AllErrors = struct {
427
427
else = > try stderr .writeByte (b ),
428
428
};
429
429
try stderr .writeByte ('\n ' );
430
- try stderr .writeByteNTimes (' ' , src .column );
430
+ // TODO basic unicode code point monospace width
431
+ const before_caret = src .span .main - src .span .start ;
432
+ // -1 since span.main includes the caret
433
+ const after_caret = src .span .end - src .span .main - | 1 ;
434
+ try stderr .writeByteNTimes (' ' , src .column - before_caret );
431
435
ttyconf .setColor (stderr , .Green );
432
- try stderr .writeAll ("^\n " );
436
+ try stderr .writeByteNTimes ('~' , before_caret );
437
+ try stderr .writeByte ('^' );
438
+ try stderr .writeByteNTimes ('~' , after_caret );
439
+ try stderr .writeByte ('\n ' );
433
440
ttyconf .setColor (stderr , .Reset );
434
441
}
435
442
}
@@ -469,7 +476,7 @@ pub const AllErrors = struct {
469
476
hasher .update (src .src_path );
470
477
std .hash .autoHash (& hasher , src .line );
471
478
std .hash .autoHash (& hasher , src .column );
472
- std .hash .autoHash (& hasher , src .byte_offset );
479
+ std .hash .autoHash (& hasher , src .span . main );
473
480
},
474
481
.plain = > | plain | {
475
482
hasher .update (plain .msg );
@@ -488,7 +495,7 @@ pub const AllErrors = struct {
488
495
mem .eql (u8 , a_src .src_path , b_src .src_path ) and
489
496
a_src .line == b_src .line and
490
497
a_src .column == b_src .column and
491
- a_src .byte_offset == b_src .byte_offset ;
498
+ a_src .span . main == b_src .span . main ;
492
499
},
493
500
.plain = > return false ,
494
501
},
@@ -527,20 +534,20 @@ pub const AllErrors = struct {
527
534
std .hash_map .default_max_load_percentage ,
528
535
).init (allocator );
529
536
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 );
537
+ const err_span = try module_err_msg .src_loc .span (module .gpa );
538
+ const err_loc = std .zig .findLineColumn (err_source .bytes , err_span . main );
532
539
533
540
for (module_err_msg .notes ) | module_note | {
534
541
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 );
542
+ const span = try module_note .src_loc .span (module .gpa );
543
+ const loc = std .zig .findLineColumn (source .bytes , span . main );
537
544
const file_path = try module_note .src_loc .file_scope .fullPath (allocator );
538
545
const note = & notes_buf [note_i ];
539
546
note .* = .{
540
547
.src = .{
541
548
.src_path = file_path ,
542
549
.msg = try allocator .dupe (u8 , module_note .msg ),
543
- .byte_offset = byte_offset ,
550
+ .span = span ,
544
551
.line = @intCast (u32 , loc .line ),
545
552
.column = @intCast (u32 , loc .column ),
546
553
.source_line = if (err_loc .eql (loc )) null else try allocator .dupe (u8 , loc .source_line ),
@@ -566,7 +573,7 @@ pub const AllErrors = struct {
566
573
.src = .{
567
574
.src_path = file_path ,
568
575
.msg = try allocator .dupe (u8 , module_err_msg .msg ),
569
- .byte_offset = err_byte_offset ,
576
+ .span = err_span ,
570
577
.line = @intCast (u32 , err_loc .line ),
571
578
.column = @intCast (u32 , err_loc .column ),
572
579
.notes = notes_buf [0.. note_i ],
@@ -593,16 +600,16 @@ pub const AllErrors = struct {
593
600
while (item_i < items_len ) : (item_i += 1 ) {
594
601
const item = file .zir .extraData (Zir .Inst .CompileErrors .Item , extra_index );
595
602
extra_index = item .end ;
596
- const err_byte_offset = blk : {
597
- const token_starts = file .tree .tokens .items (.start );
603
+ const err_span = blk : {
598
604
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 ];
605
+ break :blk Module .SrcLoc .nodeToSpan (& file .tree , item .data .node );
602
606
}
603
- break :blk token_starts [item .data .token ] + item .data .byte_offset ;
607
+ const token_starts = file .tree .tokens .items (.start );
608
+ const start = token_starts [item .data .token ] + item .data .byte_offset ;
609
+ const end = start + @intCast (u32 , file .tree .tokenSlice (item .data .token ).len );
610
+ break :blk Module.SrcLoc.Span { .start = start , .end = end , .main = start };
604
611
};
605
- const err_loc = std .zig .findLineColumn (file .source , err_byte_offset );
612
+ const err_loc = std .zig .findLineColumn (file .source , err_span . main );
606
613
607
614
var notes : []Message = &[0 ]Message {};
608
615
if (item .data .notes != 0 ) {
@@ -612,22 +619,22 @@ pub const AllErrors = struct {
612
619
for (notes ) | * note , i | {
613
620
const note_item = file .zir .extraData (Zir .Inst .CompileErrors .Item , body [i ]);
614
621
const msg = file .zir .nullTerminatedString (note_item .data .msg );
615
- const byte_offset = blk : {
616
- const token_starts = file .tree .tokens .items (.start );
622
+ const span = blk : {
617
623
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 ];
624
+ break :blk Module .SrcLoc .nodeToSpan (& file .tree , note_item .data .node );
621
625
}
622
- break :blk token_starts [note_item .data .token ] + note_item .data .byte_offset ;
626
+ const token_starts = file .tree .tokens .items (.start );
627
+ const start = token_starts [note_item .data .token ] + note_item .data .byte_offset ;
628
+ const end = start + @intCast (u32 , file .tree .tokenSlice (note_item .data .token ).len );
629
+ break :blk Module.SrcLoc.Span { .start = start , .end = end , .main = start };
623
630
};
624
- const loc = std .zig .findLineColumn (file .source , byte_offset );
631
+ const loc = std .zig .findLineColumn (file .source , span . main );
625
632
626
633
note .* = .{
627
634
.src = .{
628
635
.src_path = try file .fullPath (arena ),
629
636
.msg = try arena .dupe (u8 , msg ),
630
- .byte_offset = byte_offset ,
637
+ .span = span ,
631
638
.line = @intCast (u32 , loc .line ),
632
639
.column = @intCast (u32 , loc .column ),
633
640
.notes = &.{}, // TODO rework this function to be recursive
@@ -642,7 +649,7 @@ pub const AllErrors = struct {
642
649
.src = .{
643
650
.src_path = try file .fullPath (arena ),
644
651
.msg = try arena .dupe (u8 , msg ),
645
- .byte_offset = err_byte_offset ,
652
+ .span = err_span ,
646
653
.line = @intCast (u32 , err_loc .line ),
647
654
.column = @intCast (u32 , err_loc .column ),
648
655
.notes = notes ,
@@ -688,7 +695,7 @@ pub const AllErrors = struct {
688
695
.src_path = try arena .dupe (u8 , src .src_path ),
689
696
.line = src .line ,
690
697
.column = src .column ,
691
- .byte_offset = src .byte_offset ,
698
+ .span = src .span ,
692
699
.source_line = if (src .source_line ) | s | try arena .dupe (u8 , s ) else null ,
693
700
.notes = try dupeList (src .notes , arena ),
694
701
} },
@@ -2662,7 +2669,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
2662
2669
.msg = try std .fmt .allocPrint (arena_allocator , "unable to build C object: {s}" , .{
2663
2670
err_msg .msg ,
2664
2671
}),
2665
- .byte_offset = 0 ,
2672
+ .span = .{ . start = 0 , . end = 1 , . main = 0 } ,
2666
2673
.line = err_msg .line ,
2667
2674
.column = err_msg .column ,
2668
2675
.source_line = null , // TODO
0 commit comments