@@ -333,7 +333,7 @@ impl FormattingError {
333333
334334 pub ( crate ) fn is_internal ( & self ) -> bool {
335335 match self . kind {
336- ErrorKind :: LineOverflow ( .. )
336+ ErrorKind :: LineOverflow { .. }
337337 | ErrorKind :: TrailingWhitespace
338338 | ErrorKind :: IoError ( _)
339339 | ErrorKind :: ParseError
@@ -354,7 +354,13 @@ 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 {
358+ overflow_start_byte,
359+ ..
360+ } => (
361+ overflow_start_byte,
362+ self . line_buffer . len ( ) - overflow_start_byte,
363+ ) ,
358364 ErrorKind :: TrailingWhitespace
359365 | ErrorKind :: DeprecatedAttr
360366 | ErrorKind :: BadAttr
@@ -564,8 +570,13 @@ impl<'a> FormatLines<'a> {
564570 }
565571
566572 // 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 ( )
573+ let max_width = self . config . max_width ( ) ;
574+ let error_kind = ErrorKind :: LineOverflow {
575+ total_line_width : self . line_len ,
576+ max_width,
577+ overflow_start_byte : self . byte_offset_at_col ( max_width) ,
578+ } ;
579+ if self . line_len > max_width
569580 && !self . is_skipped_line ( )
570581 && self . should_report_error ( kind, & error_kind)
571582 {
@@ -600,6 +611,22 @@ impl<'a> FormatLines<'a> {
600611 }
601612 }
602613
614+ /// Inverse of `Self::char`'s column accounting: walk `line_buffer` with
615+ /// the same rule (tab = `tab_spaces` cols, every other char = 1 col) and
616+ /// return the byte offset where the accumulated column count first reaches
617+ /// `target_col`. Returns `line_buffer.len()` if the line is shorter.
618+ fn byte_offset_at_col ( & self , target_col : usize ) -> usize {
619+ let tab_spaces = self . config . tab_spaces ( ) ;
620+ let mut col = 0 ;
621+ for ( idx, ch) in self . line_buffer . char_indices ( ) {
622+ if col >= target_col {
623+ return idx;
624+ }
625+ col += if ch == '\t' { tab_spaces } else { 1 } ;
626+ }
627+ self . line_buffer . len ( )
628+ }
629+
603630 fn push_err ( & mut self , kind : ErrorKind , is_comment : bool , is_string : bool ) {
604631 self . errors . push ( FormattingError {
605632 line : self . cur_line ,
@@ -621,7 +648,7 @@ impl<'a> FormatLines<'a> {
621648 } ;
622649
623650 match error_kind {
624- ErrorKind :: LineOverflow ( .. ) => {
651+ ErrorKind :: LineOverflow { .. } => {
625652 self . config . error_on_line_overflow ( ) && allow_error_report
626653 }
627654 ErrorKind :: TrailingWhitespace | ErrorKind :: LostComment => allow_error_report,
0 commit comments