@@ -38,6 +38,7 @@ const TAG_FULL_SPAN: u8 = 0;
3838// A partial span with no location information, encoded only with a `SyntaxContext`
3939const TAG_PARTIAL_SPAN : u8 = 1 ;
4040const TAG_RELATIVE_SPAN : u8 = 2 ;
41+ const TAG_RELATIVE_OUTER_SPAN : u8 = 3 ;
4142
4243const TAG_SYNTAX_CONTEXT : u8 = 0 ;
4344const TAG_EXPN_DATA : u8 = 1 ;
@@ -654,6 +655,16 @@ impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> {
654655 let enclosing = self . tcx . source_span_untracked ( parent. unwrap ( ) ) . data_untracked ( ) ;
655656 ( enclosing. lo + BytePos :: from_u32 ( dlo) , enclosing. lo + BytePos :: from_u32 ( dto) )
656657 }
658+ TAG_RELATIVE_OUTER_SPAN => {
659+ let dlo = isize:: decode ( self ) ;
660+ let dto = isize:: decode ( self ) ;
661+
662+ let enclosing = self . tcx . source_span_untracked ( parent. unwrap ( ) ) . data_untracked ( ) ;
663+ let reference = enclosing. lo . to_u32 ( ) as isize ;
664+ let lo = BytePos :: from_usize ( ( reference + dlo) as usize ) ;
665+ let hi = BytePos :: from_usize ( ( reference + dto) as usize ) ;
666+ ( lo, hi)
667+ }
657668 TAG_FULL_SPAN => {
658669 let file_lo_index = SourceFileIndex :: decode ( self ) ;
659670 let line_lo = usize:: decode ( self ) ;
@@ -892,30 +903,33 @@ impl<'a, 'tcx> SpanEncoder for CacheEncoder<'a, 'tcx> {
892903 return TAG_PARTIAL_SPAN . encode ( self ) ;
893904 }
894905
895- if let Some ( parent) = span_data. parent {
896- let enclosing = self . tcx . source_span_untracked ( parent) . data_untracked ( ) ;
897- if enclosing. contains ( span_data) {
898- TAG_RELATIVE_SPAN . encode ( self ) ;
899- ( span_data. lo - enclosing. lo ) . to_u32 ( ) . encode ( self ) ;
900- ( span_data. hi - enclosing. lo ) . to_u32 ( ) . encode ( self ) ;
901- return ;
902- }
906+ let parent =
907+ span_data. parent . map ( |parent| self . tcx . source_span_untracked ( parent) . data_untracked ( ) ) ;
908+ if let Some ( parent) = parent
909+ && parent. contains ( span_data)
910+ {
911+ TAG_RELATIVE_SPAN . encode ( self ) ;
912+ ( span_data. lo - parent. lo ) . to_u32 ( ) . encode ( self ) ;
913+ ( span_data. hi - parent. lo ) . to_u32 ( ) . encode ( self ) ;
914+ return ;
903915 }
904916
905- let pos = self . source_map . byte_pos_to_line_and_col ( span_data . lo ) ;
906- let partial_span = match & pos {
907- Some ( ( file_lo , _ , _ ) ) => !file_lo . contains ( span_data . hi ) ,
908- None => true ,
917+ let Some ( ( file_lo , line_lo , col_lo ) ) =
918+ self . source_map . byte_pos_to_line_and_col ( span_data . lo )
919+ else {
920+ return TAG_PARTIAL_SPAN . encode ( self ) ;
909921 } ;
910922
911- if partial_span {
912- return TAG_PARTIAL_SPAN . encode ( self ) ;
923+ if let Some ( parent) = parent
924+ && file_lo. contains ( parent. lo )
925+ {
926+ TAG_RELATIVE_OUTER_SPAN . encode ( self ) ;
927+ ( span_data. lo . to_u32 ( ) as isize - parent. lo . to_u32 ( ) as isize ) . encode ( self ) ;
928+ ( span_data. hi . to_u32 ( ) as isize - parent. lo . to_u32 ( ) as isize ) . encode ( self ) ;
929+ return ;
913930 }
914931
915- let ( file_lo, line_lo, col_lo) = pos. unwrap ( ) ;
916-
917932 let len = span_data. hi - span_data. lo ;
918-
919933 let source_file_index = self . source_file_index ( file_lo) ;
920934
921935 TAG_FULL_SPAN . encode ( self ) ;
0 commit comments