@@ -177,15 +177,17 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
177177 // previously saved offset must be smaller than the current position.
178178 let offset = s. opaque . position ( ) - last_location;
179179 if offset < last_location {
180- SpanEncodingMode :: RelativeOffset ( offset) . encode ( s)
180+ SpanTag :: indirect ( true ) . encode ( s) ;
181+ offset. encode ( s) ;
181182 } else {
182- SpanEncodingMode :: AbsoluteOffset ( last_location) . encode ( s)
183+ SpanTag :: indirect ( false ) . encode ( s) ;
184+ last_location. encode ( s) ;
183185 }
184186 }
185187 Entry :: Vacant ( v) => {
186188 let position = s. opaque . position ( ) ;
187189 v. insert ( position) ;
188- SpanEncodingMode :: Direct . encode ( s ) ;
190+ // Data is encoded with a SpanTag prefix (see below).
189191 self . data ( ) . encode ( s) ;
190192 }
191193 }
@@ -225,14 +227,15 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SpanData {
225227 // IMPORTANT: If this is ever changed, be sure to update
226228 // `rustc_span::hygiene::raw_encode_expn_id` to handle
227229 // encoding `ExpnData` for proc-macro crates.
228- if s. is_proc_macro {
229- SyntaxContext :: root ( ) . encode ( s) ;
230- } else {
231- self . ctxt . encode ( s) ;
232- }
230+ let ctxt = if s. is_proc_macro { SyntaxContext :: root ( ) } else { self . ctxt } ;
233231
234232 if self . is_dummy ( ) {
235- return TAG_PARTIAL_SPAN . encode ( s) ;
233+ let tag = SpanTag :: new ( SpanKind :: Partial , ctxt, 0 ) ;
234+ tag. encode ( s) ;
235+ if tag. context ( ) . is_none ( ) {
236+ ctxt. encode ( s) ;
237+ }
238+ return ;
236239 }
237240
238241 // The Span infrastructure should make sure that this invariant holds:
@@ -250,7 +253,12 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SpanData {
250253 if !source_file. contains ( self . hi ) {
251254 // Unfortunately, macro expansion still sometimes generates Spans
252255 // that malformed in this way.
253- return TAG_PARTIAL_SPAN . encode ( s) ;
256+ let tag = SpanTag :: new ( SpanKind :: Partial , ctxt, 0 ) ;
257+ tag. encode ( s) ;
258+ if tag. context ( ) . is_none ( ) {
259+ ctxt. encode ( s) ;
260+ }
261+ return ;
254262 }
255263
256264 // There are two possible cases here:
@@ -269,7 +277,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SpanData {
269277 // if we're a proc-macro crate.
270278 // This allows us to avoid loading the dependencies of proc-macro crates: all of
271279 // the information we need to decode `Span`s is stored in the proc-macro crate.
272- let ( tag , metadata_index) = if source_file. is_imported ( ) && !s. is_proc_macro {
280+ let ( kind , metadata_index) = if source_file. is_imported ( ) && !s. is_proc_macro {
273281 // To simplify deserialization, we 'rebase' this span onto the crate it originally came
274282 // from (the crate that 'owns' the file it references. These rebased 'lo' and 'hi'
275283 // values are relative to the source map information for the 'foreign' crate whose
@@ -287,7 +295,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SpanData {
287295 }
288296 } ;
289297
290- ( TAG_VALID_SPAN_FOREIGN , metadata_index)
298+ ( SpanKind :: Foreign , metadata_index)
291299 } else {
292300 // Record the fact that we need to encode the data for this `SourceFile`
293301 let source_files =
@@ -296,7 +304,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SpanData {
296304 let metadata_index: u32 =
297305 metadata_index. try_into ( ) . expect ( "cannot export more than U32_MAX files" ) ;
298306
299- ( TAG_VALID_SPAN_LOCAL , metadata_index)
307+ ( SpanKind :: Local , metadata_index)
300308 } ;
301309
302310 // Encode the start position relative to the file start, so we profit more from the
@@ -307,14 +315,20 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SpanData {
307315 // from the variable-length integer encoding that we use.
308316 let len = self . hi - self . lo ;
309317
318+ let tag = SpanTag :: new ( kind, ctxt, len. 0 as usize ) ;
310319 tag. encode ( s) ;
320+ if tag. context ( ) . is_none ( ) {
321+ ctxt. encode ( s) ;
322+ }
311323 lo. encode ( s) ;
312- len. encode ( s) ;
324+ if tag. length ( ) . is_none ( ) {
325+ len. encode ( s) ;
326+ }
313327
314328 // Encode the index of the `SourceFile` for the span, in order to make decoding faster.
315329 metadata_index. encode ( s) ;
316330
317- if tag == TAG_VALID_SPAN_FOREIGN {
331+ if kind == SpanKind :: Foreign {
318332 // This needs to be two lines to avoid holding the `s.source_file_cache`
319333 // while calling `cnum.encode(s)`
320334 let cnum = s. source_file_cache . 0 . cnum ;
0 commit comments