@@ -32,8 +32,8 @@ pub mod edition;
32
32
use edition:: Edition ;
33
33
pub mod hygiene;
34
34
pub use hygiene:: SyntaxContext ;
35
+ use hygiene:: Transparency ;
35
36
pub use hygiene:: { DesugaringKind , ExpnData , ExpnId , ExpnKind , ForLoopLoc , MacroKind } ;
36
- use hygiene:: { Transparency , NUM_TRANSPARENCIES } ;
37
37
pub mod def_id;
38
38
use def_id:: { CrateNum , DefId , LOCAL_CRATE } ;
39
39
mod span_encoding;
@@ -1814,47 +1814,51 @@ impl<CTX: HashStableContext> HashStable<CTX> for SyntaxContext {
1814
1814
TAG_NO_EXPANSION . hash_stable ( ctx, hasher) ;
1815
1815
} else {
1816
1816
TAG_EXPANSION . hash_stable ( ctx, hasher) ;
1817
+ let ( expn_id, transparency) = self . outer_mark ( ) ;
1818
+ expn_id. hash_stable ( ctx, hasher) ;
1819
+ transparency. hash_stable ( ctx, hasher) ;
1820
+ }
1821
+ }
1822
+ }
1817
1823
1818
- // Since the same expansion context is usually referenced many
1819
- // times, we cache a stable hash of it and hash that instead of
1820
- // recursing every time.
1821
- thread_local ! {
1822
- static CACHE : RefCell <Vec <Option <[ Option <u64 >; NUM_TRANSPARENCIES ] >>> = Default :: default ( ) ;
1823
- }
1824
+ impl < CTX : HashStableContext > HashStable < CTX > for ExpnId {
1825
+ fn hash_stable ( & self , ctx : & mut CTX , hasher : & mut StableHasher ) {
1826
+ // Since the same expansion context is usually referenced many
1827
+ // times, we cache a stable hash of it and hash that instead of
1828
+ // recursing every time.
1829
+ thread_local ! {
1830
+ static CACHE : RefCell <Vec <Option <Fingerprint >>> = Default :: default ( ) ;
1831
+ }
1824
1832
1825
- let sub_hash: u64 = CACHE . with ( |cache| {
1826
- let ( expn_id, transparency, _) = self . outer_mark_with_data ( ) ;
1827
- let index = expn_id. as_u32 ( ) as usize ;
1833
+ const TAG_ROOT : u8 = 0 ;
1834
+ const TAG_NOT_ROOT : u8 = 1 ;
1828
1835
1829
- if let Some ( sub_hash_cache) = cache. borrow ( ) . get ( index) . copied ( ) . flatten ( ) {
1830
- if let Some ( sub_hash) = sub_hash_cache[ transparency as usize ] {
1831
- return sub_hash;
1832
- }
1833
- }
1836
+ if * self == ExpnId :: root ( ) {
1837
+ TAG_ROOT . hash_stable ( ctx, hasher) ;
1838
+ return ;
1839
+ }
1834
1840
1835
- let new_len = index + 1 ;
1841
+ TAG_NOT_ROOT . hash_stable ( ctx, hasher) ;
1842
+ let index = self . as_u32 ( ) as usize ;
1836
1843
1837
- let mut hasher = StableHasher :: new ( ) ;
1838
- expn_id. expn_data ( ) . hash_stable ( ctx, & mut hasher) ;
1839
- transparency. hash_stable ( ctx, & mut hasher) ;
1844
+ let res = CACHE . with ( |cache| cache. borrow ( ) . get ( index) . copied ( ) . flatten ( ) ) ;
1845
+
1846
+ if let Some ( res) = res {
1847
+ res. hash_stable ( ctx, hasher) ;
1848
+ } else {
1849
+ let new_len = index + 1 ;
1840
1850
1841
- let sub_hash: Fingerprint = hasher. finish ( ) ;
1842
- let sub_hash = sub_hash. to_smaller_hash ( ) ;
1851
+ let mut sub_hasher = StableHasher :: new ( ) ;
1852
+ self . expn_data ( ) . hash_stable ( ctx, & mut sub_hasher) ;
1853
+ let sub_hash: Fingerprint = sub_hasher. finish ( ) ;
1843
1854
1855
+ CACHE . with ( |cache| {
1844
1856
let mut cache = cache. borrow_mut ( ) ;
1845
1857
if cache. len ( ) < new_len {
1846
1858
cache. resize ( new_len, None ) ;
1847
1859
}
1848
- if let Some ( mut sub_hash_cache) = cache[ index] {
1849
- sub_hash_cache[ transparency as usize ] = Some ( sub_hash) ;
1850
- } else {
1851
- let mut sub_hash_cache = [ None ; NUM_TRANSPARENCIES ] ;
1852
- sub_hash_cache[ transparency as usize ] = Some ( sub_hash) ;
1853
- cache[ index] = Some ( sub_hash_cache) ;
1854
- }
1855
- sub_hash
1860
+ cache[ index] . replace ( sub_hash) . expect_none ( "Cache slot was filled" ) ;
1856
1861
} ) ;
1857
-
1858
1862
sub_hash. hash_stable ( ctx, hasher) ;
1859
1863
}
1860
1864
}
0 commit comments