@@ -354,7 +354,9 @@ impl FormattingError {
354354 // (space, target)
355355 pub ( crate ) fn format_len ( & self ) -> ( usize , usize ) {
356356 match self . kind {
357- ErrorKind :: LineOverflow ( found, max) => ( max, found - max) ,
357+ ErrorKind :: LineOverflow ( _, _, byte_start) => {
358+ ( byte_start, self . line_buffer . len ( ) - byte_start)
359+ }
358360 ErrorKind :: TrailingWhitespace
359361 | ErrorKind :: DeprecatedAttr
360362 | ErrorKind :: BadAttr
@@ -564,8 +566,10 @@ impl<'a> FormatLines<'a> {
564566 }
565567
566568 // Check for any line width errors we couldn't correct.
567- let error_kind = ErrorKind :: LineOverflow ( self . line_len , self . config . max_width ( ) ) ;
568- if self . line_len > self . config . max_width ( )
569+ let max = self . config . max_width ( ) ;
570+ let error_kind =
571+ ErrorKind :: LineOverflow ( self . line_len , max, self . byte_offset_at_col ( max) ) ;
572+ if self . line_len > max
569573 && !self . is_skipped_line ( )
570574 && self . should_report_error ( kind, & error_kind)
571575 {
@@ -600,6 +604,22 @@ impl<'a> FormatLines<'a> {
600604 }
601605 }
602606
607+ /// Inverse of `Self::char`'s column accounting: walk `line_buffer` with
608+ /// the same rule (tab = `tab_spaces` cols, every other char = 1 col) and
609+ /// return the byte offset where the accumulated column count first reaches
610+ /// `target_col`. Returns `line_buffer.len()` if the line is shorter.
611+ fn byte_offset_at_col ( & self , target_col : usize ) -> usize {
612+ let tab_spaces = self . config . tab_spaces ( ) ;
613+ let mut col = 0 ;
614+ for ( idx, ch) in self . line_buffer . char_indices ( ) {
615+ if col >= target_col {
616+ return idx;
617+ }
618+ col += if ch == '\t' { tab_spaces } else { 1 } ;
619+ }
620+ self . line_buffer . len ( )
621+ }
622+
603623 fn push_err ( & mut self , kind : ErrorKind , is_comment : bool , is_string : bool ) {
604624 self . errors . push ( FormattingError {
605625 line : self . cur_line ,
0 commit comments