@@ -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;
@@ -1823,47 +1823,51 @@ impl<CTX: HashStableContext> HashStable<CTX> for SyntaxContext {
1823
1823
TAG_NO_EXPANSION . hash_stable ( ctx, hasher) ;
1824
1824
} else {
1825
1825
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
+ }
1826
1832
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
+ }
1833
1841
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 ;
1837
1844
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
+ }
1843
1849
1844
- let new_len = index + 1 ;
1850
+ TAG_NOT_ROOT . hash_stable ( ctx, hasher) ;
1851
+ let index = self . as_u32 ( ) as usize ;
1845
1852
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 ;
1849
1859
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 ( ) ;
1852
1863
1864
+ CACHE . with ( |cache| {
1853
1865
let mut cache = cache. borrow_mut ( ) ;
1854
1866
if cache. len ( ) < new_len {
1855
1867
cache. resize ( new_len, None ) ;
1856
1868
}
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" ) ;
1865
1870
} ) ;
1866
-
1867
1871
sub_hash. hash_stable ( ctx, hasher) ;
1868
1872
}
1869
1873
}
0 commit comments