@@ -235,16 +235,14 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
235235 ( source_map. files ( ) [ source_file_index] . clone ( ) , source_file_index) ;
236236 }
237237 let ( ref source_file, source_file_index) = s. source_file_cache ;
238+ debug_assert ! ( source_file. contains( span. lo) ) ;
238239
239240 if !source_file. contains ( span. hi ) {
240241 // Unfortunately, macro expansion still sometimes generates Spans
241242 // that malformed in this way.
242243 return TAG_PARTIAL_SPAN . encode ( s) ;
243244 }
244245
245- // Length is independent of the span provenance.
246- let len = span. hi - span. lo ;
247-
248246 // There are two possible cases here:
249247 // 1. This span comes from a 'foreign' crate - e.g. some crate upstream of the
250248 // crate we are writing metadata for. When the metadata for *this* crate gets
@@ -261,7 +259,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
261259 // if we're a proc-macro crate.
262260 // This allows us to avoid loading the dependencies of proc-macro crates: all of
263261 // the information we need to decode `Span`s is stored in the proc-macro crate.
264- let ( tag, lo , metadata_index) = if source_file. is_imported ( ) && !s. is_proc_macro {
262+ let ( tag, metadata_index) = if source_file. is_imported ( ) && !s. is_proc_macro {
265263 // To simplify deserialization, we 'rebase' this span onto the crate it originally came from
266264 // (the crate that 'owns' the file it references. These rebased 'lo' and 'hi' values
267265 // are relative to the source map information for the 'foreign' crate whose CrateNum
@@ -271,18 +269,15 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
271269 //
272270 // All of this logic ensures that the final result of deserialization is a 'normal'
273271 // Span that can be used without any additional trouble.
274- let ( external_start_pos , metadata_index) = {
272+ let metadata_index = {
275273 // Introduce a new scope so that we drop the 'lock()' temporary
276274 match & * source_file. external_src . lock ( ) {
277- ExternalSource :: Foreign { original_start_pos, metadata_index, .. } => {
278- ( * original_start_pos, * metadata_index)
279- }
275+ ExternalSource :: Foreign { metadata_index, .. } => * metadata_index,
280276 src => panic ! ( "Unexpected external source {:?}" , src) ,
281277 }
282278 } ;
283- let lo = ( span. lo - source_file. start_pos ) + external_start_pos;
284279
285- ( TAG_VALID_SPAN_FOREIGN , lo , metadata_index)
280+ ( TAG_VALID_SPAN_FOREIGN , metadata_index)
286281 } else {
287282 // Record the fact that we need to encode the data for this `SourceFile`
288283 let source_files =
@@ -291,14 +286,19 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
291286 let metadata_index: u32 =
292287 metadata_index. try_into ( ) . expect ( "cannot export more than U32_MAX files" ) ;
293288
294- ( TAG_VALID_SPAN_LOCAL , span . lo , metadata_index)
289+ ( TAG_VALID_SPAN_LOCAL , metadata_index)
295290 } ;
296291
297- tag. encode ( s) ;
298- lo. encode ( s) ;
292+ // Encode the start position relative to the file start, so we profit more from the
293+ // variable-length integer encoding.
294+ let lo = span. lo - source_file. start_pos ;
299295
300296 // Encode length which is usually less than span.hi and profits more
301297 // from the variable-length integer encoding that we use.
298+ let len = span. hi - span. lo ;
299+
300+ tag. encode ( s) ;
301+ lo. encode ( s) ;
302302 len. encode ( s) ;
303303
304304 // Encode the index of the `SourceFile` for the span, in order to make decoding faster.
0 commit comments