@@ -177,15 +177,17 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
177
177
// previously saved offset must be smaller than the current position.
178
178
let offset = s. opaque . position ( ) - last_location;
179
179
if offset < last_location {
180
- SpanEncodingMode :: RelativeOffset ( offset) . encode ( s)
180
+ SpanTag :: indirect ( true ) . encode ( s) ;
181
+ offset. encode ( s) ;
181
182
} else {
182
- SpanEncodingMode :: AbsoluteOffset ( last_location) . encode ( s)
183
+ SpanTag :: indirect ( false ) . encode ( s) ;
184
+ last_location. encode ( s) ;
183
185
}
184
186
}
185
187
Entry :: Vacant ( v) => {
186
188
let position = s. opaque . position ( ) ;
187
189
v. insert ( position) ;
188
- SpanEncodingMode :: Direct . encode ( s ) ;
190
+ // Data is encoded with a SpanTag prefix (see below).
189
191
self . data ( ) . encode ( s) ;
190
192
}
191
193
}
@@ -225,14 +227,15 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SpanData {
225
227
// IMPORTANT: If this is ever changed, be sure to update
226
228
// `rustc_span::hygiene::raw_encode_expn_id` to handle
227
229
// 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 } ;
233
231
234
232
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 ;
236
239
}
237
240
238
241
// The Span infrastructure should make sure that this invariant holds:
@@ -250,7 +253,12 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SpanData {
250
253
if !source_file. contains ( self . hi ) {
251
254
// Unfortunately, macro expansion still sometimes generates Spans
252
255
// 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 ;
254
262
}
255
263
256
264
// There are two possible cases here:
@@ -269,7 +277,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SpanData {
269
277
// if we're a proc-macro crate.
270
278
// This allows us to avoid loading the dependencies of proc-macro crates: all of
271
279
// 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 {
273
281
// To simplify deserialization, we 'rebase' this span onto the crate it originally came
274
282
// from (the crate that 'owns' the file it references. These rebased 'lo' and 'hi'
275
283
// 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 {
287
295
}
288
296
} ;
289
297
290
- ( TAG_VALID_SPAN_FOREIGN , metadata_index)
298
+ ( SpanKind :: Foreign , metadata_index)
291
299
} else {
292
300
// Record the fact that we need to encode the data for this `SourceFile`
293
301
let source_files =
@@ -296,7 +304,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SpanData {
296
304
let metadata_index: u32 =
297
305
metadata_index. try_into ( ) . expect ( "cannot export more than U32_MAX files" ) ;
298
306
299
- ( TAG_VALID_SPAN_LOCAL , metadata_index)
307
+ ( SpanKind :: Local , metadata_index)
300
308
} ;
301
309
302
310
// 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 {
307
315
// from the variable-length integer encoding that we use.
308
316
let len = self . hi - self . lo ;
309
317
318
+ let tag = SpanTag :: new ( kind, ctxt, len. 0 as usize ) ;
310
319
tag. encode ( s) ;
320
+ if tag. context ( ) . is_none ( ) {
321
+ ctxt. encode ( s) ;
322
+ }
311
323
lo. encode ( s) ;
312
- len. encode ( s) ;
324
+ if tag. length ( ) . is_none ( ) {
325
+ len. encode ( s) ;
326
+ }
313
327
314
328
// Encode the index of the `SourceFile` for the span, in order to make decoding faster.
315
329
metadata_index. encode ( s) ;
316
330
317
- if tag == TAG_VALID_SPAN_FOREIGN {
331
+ if kind == SpanKind :: Foreign {
318
332
// This needs to be two lines to avoid holding the `s.source_file_cache`
319
333
// while calling `cnum.encode(s)`
320
334
let cnum = s. source_file_cache . 0 . cnum ;
0 commit comments