@@ -375,38 +375,52 @@ impl FileInfo {
375375 }
376376
377377 fn byte_range ( & mut self , span : Span ) -> Range < usize > {
378- let lo_char = ( span. lo - self . span . lo ) as usize ;
378+ self . byte ( span. lo ) ..self . byte ( span. hi )
379+ }
380+
381+ fn byte ( & mut self , ch : u32 ) -> usize {
382+ let char_index = ( ch - self . span . lo ) as usize ;
379383
380384 // Look up offset of the largest already-computed char index that is
381- // less than or equal to the current requested one. We resume counting
382- // chars from that point.
383- let ( & last_char_index, & last_byte_offset) = self
385+ // less than or equal to the current requested one.
386+ let ( & previous_char_index, & previous_byte_offset) = self
384387 . char_index_to_byte_offset
385- . range ( ..=lo_char )
388+ . range ( ..=char_index )
386389 . next_back ( )
387390 . unwrap_or ( ( & 0 , & 0 ) ) ;
388391
389- let lo_byte = if last_char_index == lo_char {
390- last_byte_offset
391- } else {
392- let total_byte_offset = match self . source_text [ last_byte_offset..]
393- . char_indices ( )
394- . nth ( lo_char - last_char_index)
392+ if previous_char_index == char_index {
393+ return previous_byte_offset;
394+ }
395+
396+ // Look up next char index that is greater than the requested one. We
397+ // resume counting chars from whichever point is closer.
398+ let byte_offset = match self . char_index_to_byte_offset . range ( char_index..) . next ( ) {
399+ Some ( ( & next_char_index, & next_byte_offset) )
400+ if next_char_index - char_index < char_index - previous_char_index =>
395401 {
396- Some ( ( additional_offset, _ch) ) => last_byte_offset + additional_offset,
397- None => self . source_text . len ( ) ,
398- } ;
399- self . char_index_to_byte_offset
400- . insert ( lo_char, total_byte_offset) ;
401- total_byte_offset
402+ self . source_text [ ..next_byte_offset]
403+ . char_indices ( )
404+ . nth_back ( next_char_index - char_index - 1 )
405+ . unwrap ( )
406+ . 0
407+ }
408+ _ => {
409+ match self . source_text [ previous_byte_offset..]
410+ . char_indices ( )
411+ . nth ( char_index - previous_char_index)
412+ {
413+ Some ( ( byte_offset_from_previous, _ch) ) => {
414+ previous_byte_offset + byte_offset_from_previous
415+ }
416+ None => self . source_text . len ( ) ,
417+ }
418+ }
402419 } ;
403420
404- let trunc_lo = & self . source_text [ lo_byte..] ;
405- let char_len = ( span. hi - span. lo ) as usize ;
406- lo_byte..match trunc_lo. char_indices ( ) . nth ( char_len) {
407- Some ( ( offset, _ch) ) => lo_byte + offset,
408- None => self . source_text . len ( ) ,
409- }
421+ self . char_index_to_byte_offset
422+ . insert ( char_index, byte_offset) ;
423+ byte_offset
410424 }
411425
412426 fn source_text ( & mut self , span : Span ) -> String {
0 commit comments