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