@@ -594,12 +594,22 @@ fn highlight_lines(err: &mut EmitterWriter,
594
594
let display_line_infos = & lines. lines [ ..display_lines] ;
595
595
let display_line_strings = & line_strings[ ..display_lines] ;
596
596
597
+ // Calculate the widest number to format evenly and fix #11715
598
+ assert ! ( display_line_infos. len( ) > 0 ) ;
599
+ let mut max_line_num = display_line_infos[ display_line_infos. len ( ) - 1 ] . line_index + 1 ;
600
+ let mut digits = 0 ;
601
+ while max_line_num > 0 {
602
+ max_line_num /= 10 ;
603
+ digits += 1 ;
604
+ }
605
+
597
606
// Print the offending lines
598
607
for ( line_info, line) in display_line_infos. iter ( ) . zip ( display_line_strings) {
599
- try!( write ! ( & mut err. dst, "{}:{} {}\n " ,
608
+ try!( write ! ( & mut err. dst, "{}:{:>width$ } {}\n " ,
600
609
fm. name,
601
610
line_info. line_index + 1 ,
602
- line) ) ;
611
+ line,
612
+ width=digits) ) ;
603
613
}
604
614
605
615
// If we elided something, put an ellipsis.
@@ -795,3 +805,64 @@ pub fn expect<T, M>(diag: &SpanHandler, opt: Option<T>, msg: M) -> T where
795
805
None => diag. handler ( ) . bug ( & msg ( ) ) ,
796
806
}
797
807
}
808
+
809
+ #[ cfg( test) ]
810
+ mod test {
811
+ use super :: { EmitterWriter , highlight_lines, Level } ;
812
+ use codemap:: { mk_sp, CodeMap , BytePos } ;
813
+ use std:: sync:: { Arc , Mutex } ;
814
+ use std:: io:: { self , Write } ;
815
+ use std:: str:: from_utf8;
816
+
817
+ // Diagnostic doesn't align properly in span where line number increases by one digit
818
+ #[ test]
819
+ fn test_hilight_suggestion_issue_11715 ( ) {
820
+ struct Sink ( Arc < Mutex < Vec < u8 > > > ) ;
821
+ impl Write for Sink {
822
+ fn write ( & mut self , data : & [ u8 ] ) -> io:: Result < usize > {
823
+ Write :: write ( & mut * self . 0 . lock ( ) . unwrap ( ) , data)
824
+ }
825
+ fn flush ( & mut self ) -> io:: Result < ( ) > { Ok ( ( ) ) }
826
+ }
827
+ let data = Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ;
828
+ let mut ew = EmitterWriter :: new ( Box :: new ( Sink ( data. clone ( ) ) ) , None ) ;
829
+ let cm = CodeMap :: new ( ) ;
830
+ let content = "abcdefg
831
+ koksi
832
+ line3
833
+ line4
834
+ cinq
835
+ line6
836
+ line7
837
+ line8
838
+ line9
839
+ line10
840
+ e-lä-vän
841
+ tolv
842
+ dreizehn
843
+ " ;
844
+ let file = cm. new_filemap ( "dummy.txt" . to_string ( ) , content. to_string ( ) ) ;
845
+ for ( i, b) in content. bytes ( ) . enumerate ( ) {
846
+ if b == b'\n' {
847
+ file. next_line ( BytePos ( i as u32 ) ) ;
848
+ }
849
+ }
850
+ let start = file. lines . borrow ( ) [ 7 ] ;
851
+ let end = file. lines . borrow ( ) [ 11 ] ;
852
+ let sp = mk_sp ( start, end) ;
853
+ let lvl = Level :: Error ;
854
+ println ! ( "span_to_lines" ) ;
855
+ let lines = cm. span_to_lines ( sp) ;
856
+ println ! ( "highlight_lines" ) ;
857
+ highlight_lines ( & mut ew, & cm, sp, lvl, lines) . unwrap ( ) ;
858
+ println ! ( "done" ) ;
859
+ let vec = data. lock ( ) . unwrap ( ) . clone ( ) ;
860
+ let vec: & [ u8 ] = & vec;
861
+ println ! ( "{}" , from_utf8( vec) . unwrap( ) ) ;
862
+ assert_eq ! ( vec, "dummy.txt: 8 \n \
863
+ dummy.txt: 9 \n \
864
+ dummy.txt:10 \n \
865
+ dummy.txt:11 \n \
866
+ dummy.txt:12 \n ". as_bytes( ) ) ;
867
+ }
868
+ }
0 commit comments