@@ -28,7 +28,7 @@ use syntax::attr;
28
28
use syntax:: codemap:: CodeMap ;
29
29
use syntax:: ext:: hygiene:: SyntaxContext ;
30
30
use syntax:: symbol:: Symbol ;
31
- use syntax_pos:: Span ;
31
+ use syntax_pos:: { Span , DUMMY_SP } ;
32
32
33
33
use rustc_data_structures:: stable_hasher:: { HashStable , StableHashingContextProvider ,
34
34
StableHasher , StableHasherResult ,
@@ -362,63 +362,52 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Span {
362
362
fn hash_stable < W : StableHasherResult > ( & self ,
363
363
hcx : & mut StableHashingContext < ' gcx > ,
364
364
hasher : & mut StableHasher < W > ) {
365
- use syntax_pos:: Pos ;
365
+ const TAG_VALID_SPAN : u8 = 0 ;
366
+ const TAG_INVALID_SPAN : u8 = 1 ;
367
+ const TAG_EXPANSION : u8 = 0 ;
368
+ const TAG_NO_EXPANSION : u8 = 1 ;
366
369
367
370
if !hcx. hash_spans {
368
371
return
369
372
}
370
373
374
+ if * self == DUMMY_SP {
375
+ return std_hash:: Hash :: hash ( & TAG_INVALID_SPAN , hasher) ;
376
+ }
377
+
371
378
// If this is not an empty or invalid span, we want to hash the last
372
379
// position that belongs to it, as opposed to hashing the first
373
380
// position past it.
374
381
let span = self . data ( ) ;
375
- let span_hi = if span. hi > span. lo {
376
- // We might end up in the middle of a multibyte character here,
377
- // but that's OK, since we are not trying to decode anything at
378
- // this position.
379
- span. hi - :: syntax_pos:: BytePos ( 1 )
380
- } else {
381
- span. hi
382
- } ;
383
382
384
- {
385
- let loc1 = hcx. codemap ( ) . byte_pos_to_line_and_col ( span. lo ) ;
386
- let loc1 = loc1. as_ref ( )
387
- . map ( |& ( ref fm, line, col) | ( & fm. name [ ..] , line, col. to_usize ( ) ) )
388
- . unwrap_or ( ( "???" , 0 , 0 ) ) ;
389
-
390
- let loc2 = hcx. codemap ( ) . byte_pos_to_line_and_col ( span_hi) ;
391
- let loc2 = loc2. as_ref ( )
392
- . map ( |& ( ref fm, line, col) | ( & fm. name [ ..] , line, col. to_usize ( ) ) )
393
- . unwrap_or ( ( "???" , 0 , 0 ) ) ;
394
-
395
- if loc1. 0 == loc2. 0 {
396
- std_hash:: Hash :: hash ( & 0u8 , hasher) ;
397
-
398
- std_hash:: Hash :: hash ( loc1. 0 , hasher) ;
399
- std_hash:: Hash :: hash ( & loc1. 1 , hasher) ;
400
- std_hash:: Hash :: hash ( & loc1. 2 , hasher) ;
401
-
402
- // Do not hash the file name twice
403
- std_hash:: Hash :: hash ( & loc2. 1 , hasher) ;
404
- std_hash:: Hash :: hash ( & loc2. 2 , hasher) ;
405
- } else {
406
- std_hash:: Hash :: hash ( & 1u8 , hasher) ;
407
-
408
- std_hash:: Hash :: hash ( loc1. 0 , hasher) ;
409
- std_hash:: Hash :: hash ( & loc1. 1 , hasher) ;
410
- std_hash:: Hash :: hash ( & loc1. 2 , hasher) ;
411
-
412
- std_hash:: Hash :: hash ( loc2. 0 , hasher) ;
413
- std_hash:: Hash :: hash ( & loc2. 1 , hasher) ;
414
- std_hash:: Hash :: hash ( & loc2. 2 , hasher) ;
383
+ if span. hi < span. lo {
384
+ return std_hash:: Hash :: hash ( & TAG_INVALID_SPAN , hasher) ;
385
+ }
386
+
387
+ let ( file_lo, line_lo, col_lo) = match hcx. codemap ( )
388
+ . byte_pos_to_line_and_col ( span. lo ) {
389
+ Some ( pos) => pos,
390
+ None => {
391
+ return std_hash:: Hash :: hash ( & TAG_INVALID_SPAN , hasher) ;
415
392
}
393
+ } ;
394
+
395
+ if !file_lo. contains ( span. hi ) {
396
+ return std_hash:: Hash :: hash ( & TAG_INVALID_SPAN , hasher) ;
416
397
}
417
398
399
+ let len = span. hi - span. lo ;
400
+
401
+ std_hash:: Hash :: hash ( & TAG_VALID_SPAN , hasher) ;
402
+ std_hash:: Hash :: hash ( & file_lo. name , hasher) ;
403
+ std_hash:: Hash :: hash ( & line_lo, hasher) ;
404
+ std_hash:: Hash :: hash ( & col_lo, hasher) ;
405
+ std_hash:: Hash :: hash ( & len, hasher) ;
406
+
418
407
if span. ctxt == SyntaxContext :: empty ( ) {
419
- 0u8 . hash_stable ( hcx, hasher) ;
408
+ TAG_NO_EXPANSION . hash_stable ( hcx, hasher) ;
420
409
} else {
421
- 1u8 . hash_stable ( hcx, hasher) ;
410
+ TAG_EXPANSION . hash_stable ( hcx, hasher) ;
422
411
span. ctxt . outer ( ) . expn_info ( ) . hash_stable ( hcx, hasher) ;
423
412
}
424
413
}
0 commit comments