@@ -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;
@@ -1814,47 +1814,51 @@ impl<CTX: HashStableContext> HashStable<CTX> for SyntaxContext {
18141814 TAG_NO_EXPANSION . hash_stable ( ctx, hasher) ;
18151815 } else {
18161816 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+ }
18171823
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+ }
18241832
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 ;
18281835
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+ }
18341840
1835- let new_len = index + 1 ;
1841+ TAG_NOT_ROOT . hash_stable ( ctx, hasher) ;
1842+ let index = self . as_u32 ( ) as usize ;
18361843
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 ;
18401850
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 ( ) ;
18431854
1855+ CACHE . with ( |cache| {
18441856 let mut cache = cache. borrow_mut ( ) ;
18451857 if cache. len ( ) < new_len {
18461858 cache. resize ( new_len, None ) ;
18471859 }
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" ) ;
18561861 } ) ;
1857-
18581862 sub_hash. hash_stable ( ctx, hasher) ;
18591863 }
18601864 }
0 commit comments