@@ -38,6 +38,7 @@ const TAG_FULL_SPAN: u8 = 0;
38
38
// A partial span with no location information, encoded only with a `SyntaxContext`
39
39
const TAG_PARTIAL_SPAN : u8 = 1 ;
40
40
const TAG_RELATIVE_SPAN : u8 = 2 ;
41
+ const TAG_RELATIVE_OUTER_SPAN : u8 = 3 ;
41
42
42
43
const TAG_SYNTAX_CONTEXT : u8 = 0 ;
43
44
const TAG_EXPN_DATA : u8 = 1 ;
@@ -659,6 +660,19 @@ impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> {
659
660
parent,
660
661
) ;
661
662
663
+ return span;
664
+ } else if tag == TAG_RELATIVE_OUTER_SPAN {
665
+ let dlo = isize:: decode ( self ) ;
666
+ let dto = isize:: decode ( self ) ;
667
+
668
+ let enclosing = self . tcx . source_span_untracked ( parent. unwrap ( ) ) . data_untracked ( ) ;
669
+ let span = Span :: new (
670
+ BytePos :: from_usize ( ( enclosing. lo . to_u32 ( ) as isize + dlo) as usize ) ,
671
+ BytePos :: from_usize ( ( enclosing. lo . to_u32 ( ) as isize + dto) as usize ) ,
672
+ ctxt,
673
+ parent,
674
+ ) ;
675
+
662
676
return span;
663
677
} else {
664
678
debug_assert_eq ! ( tag, TAG_FULL_SPAN ) ;
@@ -897,30 +911,33 @@ impl<'a, 'tcx> SpanEncoder for CacheEncoder<'a, 'tcx> {
897
911
return TAG_PARTIAL_SPAN . encode ( self ) ;
898
912
}
899
913
900
- if let Some ( parent) = span_data. parent {
901
- let enclosing = self . tcx . source_span_untracked ( parent) . data_untracked ( ) ;
902
- if enclosing. contains ( span_data) {
903
- TAG_RELATIVE_SPAN . encode ( self ) ;
904
- ( span_data. lo - enclosing. lo ) . to_u32 ( ) . encode ( self ) ;
905
- ( span_data. hi - enclosing. lo ) . to_u32 ( ) . encode ( self ) ;
906
- return ;
907
- }
914
+ let parent =
915
+ span_data. parent . map ( |parent| self . tcx . source_span_untracked ( parent) . data_untracked ( ) ) ;
916
+ if let Some ( parent) = parent
917
+ && parent. contains ( span_data)
918
+ {
919
+ TAG_RELATIVE_SPAN . encode ( self ) ;
920
+ ( span_data. lo - parent. lo ) . to_u32 ( ) . encode ( self ) ;
921
+ ( span_data. hi - parent. lo ) . to_u32 ( ) . encode ( self ) ;
922
+ return ;
908
923
}
909
924
910
- let pos = self . source_map . byte_pos_to_line_and_col ( span_data . lo ) ;
911
- let partial_span = match & pos {
912
- Some ( ( file_lo , _ , _ ) ) => !file_lo . contains ( span_data . hi ) ,
913
- None => true ,
925
+ let Some ( ( file_lo , line_lo , col_lo ) ) =
926
+ self . source_map . byte_pos_to_line_and_col ( span_data . lo )
927
+ else {
928
+ return TAG_PARTIAL_SPAN . encode ( self ) ;
914
929
} ;
915
930
916
- if partial_span {
917
- return TAG_PARTIAL_SPAN . encode ( self ) ;
931
+ if let Some ( parent) = parent
932
+ && file_lo. contains ( parent. lo )
933
+ {
934
+ TAG_RELATIVE_OUTER_SPAN . encode ( self ) ;
935
+ ( span_data. lo . to_u32 ( ) as isize - parent. lo . to_u32 ( ) as isize ) . encode ( self ) ;
936
+ ( span_data. hi . to_u32 ( ) as isize - parent. lo . to_u32 ( ) as isize ) . encode ( self ) ;
937
+ return ;
918
938
}
919
939
920
- let ( file_lo, line_lo, col_lo) = pos. unwrap ( ) ;
921
-
922
940
let len = span_data. hi - span_data. lo ;
923
-
924
941
let source_file_index = self . source_file_index ( file_lo) ;
925
942
926
943
TAG_FULL_SPAN . encode ( self ) ;
0 commit comments