@@ -23,7 +23,7 @@ use rustc_span::hygiene::{
2323} ;
2424use rustc_span:: source_map:: { SourceMap , StableSourceFileId } ;
2525use rustc_span:: CachingSourceMapView ;
26- use rustc_span:: { BytePos , ExpnData , ExpnHash , SourceFile , Span , DUMMY_SP } ;
26+ use rustc_span:: { BytePos , ExpnData , ExpnHash , Pos , SourceFile , Span } ;
2727use std:: collections:: hash_map:: Entry ;
2828use std:: mem;
2929
@@ -33,6 +33,7 @@ const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
3333const TAG_FULL_SPAN : u8 = 0 ;
3434// A partial span with no location information, encoded only with a `SyntaxContext`
3535const TAG_PARTIAL_SPAN : u8 = 1 ;
36+ const TAG_RELATIVE_SPAN : u8 = 2 ;
3637
3738const TAG_SYNTAX_CONTEXT : u8 = 0 ;
3839const TAG_EXPN_DATA : u8 = 1 ;
@@ -829,11 +830,25 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
829830
830831impl < ' a , ' tcx > Decodable < CacheDecoder < ' a , ' tcx > > for Span {
831832 fn decode ( decoder : & mut CacheDecoder < ' a , ' tcx > ) -> Result < Self , String > {
833+ let ctxt = SyntaxContext :: decode ( decoder) ?;
834+ let parent = Option :: < LocalDefId > :: decode ( decoder) ?;
832835 let tag: u8 = Decodable :: decode ( decoder) ?;
833836
834837 if tag == TAG_PARTIAL_SPAN {
835- let ctxt = SyntaxContext :: decode ( decoder) ?;
836- return Ok ( DUMMY_SP . with_ctxt ( ctxt) ) ;
838+ return Ok ( Span :: new ( BytePos ( 0 ) , BytePos ( 0 ) , ctxt, parent) ) ;
839+ } else if tag == TAG_RELATIVE_SPAN {
840+ let dlo = u32:: decode ( decoder) ?;
841+ let dto = u32:: decode ( decoder) ?;
842+
843+ let enclosing = decoder. tcx . definitions_untracked ( ) . def_span ( parent. unwrap ( ) ) . data ( ) ;
844+ let span = Span :: new (
845+ enclosing. lo + BytePos :: from_u32 ( dlo) ,
846+ enclosing. lo + BytePos :: from_u32 ( dto) ,
847+ ctxt,
848+ parent,
849+ ) ;
850+
851+ return Ok ( span) ;
837852 } else {
838853 debug_assert_eq ! ( tag, TAG_FULL_SPAN ) ;
839854 }
@@ -842,13 +857,12 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
842857 let line_lo = usize:: decode ( decoder) ?;
843858 let col_lo = BytePos :: decode ( decoder) ?;
844859 let len = BytePos :: decode ( decoder) ?;
845- let ctxt = SyntaxContext :: decode ( decoder) ?;
846860
847861 let file_lo = decoder. file_index_to_file ( file_lo_index) ;
848862 let lo = file_lo. lines [ line_lo - 1 ] + col_lo;
849863 let hi = lo + len;
850864
851- Ok ( Span :: new ( lo, hi, ctxt, None ) )
865+ Ok ( Span :: new ( lo, hi, ctxt, parent ) )
852866 }
853867}
854868
@@ -1009,9 +1023,21 @@ where
10091023{
10101024 fn encode ( & self , s : & mut CacheEncoder < ' a , ' tcx , E > ) -> Result < ( ) , E :: Error > {
10111025 let span_data = self . data ( ) ;
1012- if self . is_dummy ( ) {
1013- TAG_PARTIAL_SPAN . encode ( s) ?;
1014- return span_data. ctxt . encode ( s) ;
1026+ span_data. ctxt . encode ( s) ?;
1027+ span_data. parent . encode ( s) ?;
1028+
1029+ if span_data. is_dummy ( ) {
1030+ return TAG_PARTIAL_SPAN . encode ( s) ;
1031+ }
1032+
1033+ if let Some ( parent) = span_data. parent {
1034+ let enclosing = s. tcx . definitions_untracked ( ) . def_span ( parent) . data ( ) ;
1035+ if enclosing. contains ( span_data) {
1036+ TAG_RELATIVE_SPAN . encode ( s) ?;
1037+ ( span_data. lo - enclosing. lo ) . to_u32 ( ) . encode ( s) ?;
1038+ ( span_data. hi - enclosing. lo ) . to_u32 ( ) . encode ( s) ?;
1039+ return Ok ( ( ) ) ;
1040+ }
10151041 }
10161042
10171043 let pos = s. source_map . byte_pos_to_line_and_col ( span_data. lo ) ;
@@ -1021,8 +1047,7 @@ where
10211047 } ;
10221048
10231049 if partial_span {
1024- TAG_PARTIAL_SPAN . encode ( s) ?;
1025- return span_data. ctxt . encode ( s) ;
1050+ return TAG_PARTIAL_SPAN . encode ( s) ;
10261051 }
10271052
10281053 let ( file_lo, line_lo, col_lo) = pos. unwrap ( ) ;
@@ -1035,8 +1060,7 @@ where
10351060 source_file_index. encode ( s) ?;
10361061 line_lo. encode ( s) ?;
10371062 col_lo. encode ( s) ?;
1038- len. encode ( s) ?;
1039- span_data. ctxt . encode ( s)
1063+ len. encode ( s)
10401064 }
10411065}
10421066
0 commit comments