]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #75134 - Aaron1011:feature/expn-data-parent-hash, r=petrochenkov
authorbors <bors@rust-lang.org>
Sun, 9 Aug 2020 14:29:42 +0000 (14:29 +0000)
committerbors <bors@rust-lang.org>
Sun, 9 Aug 2020 14:29:42 +0000 (14:29 +0000)
Hash parent ExpnData

cc https://github.com/rust-lang/rust/pull/72121#discussion_r460528326

1  2 
src/librustc_span/hygiene.rs
src/librustc_span/lib.rs

index fe5370b9644fc8585cae52d04b9f9654f37cf43b,b5ae48b058c6e9f03ccb42489d9a30ceb4bf7345..4e21d566071ef609da18d9c34dcf87fb7a452b01
@@@ -80,8 -80,6 +80,6 @@@ pub enum Transparency 
      Opaque,
  }
  
- pub(crate) const NUM_TRANSPARENCIES: usize = 3;
  impl ExpnId {
      pub fn fresh(expn_data: Option<ExpnData>) -> Self {
          HygieneData::with(|data| data.fresh_expn(expn_data))
@@@ -618,6 -616,11 +616,11 @@@ impl SyntaxContext 
          HygieneData::with(|data| data.expn_data(data.outer_expn(self)).clone())
      }
  
+     #[inline]
+     pub fn outer_mark(self) -> (ExpnId, Transparency) {
+         HygieneData::with(|data| data.outer_mark(self))
+     }
      #[inline]
      pub fn outer_mark_with_data(self) -> (ExpnId, Transparency, ExpnData) {
          HygieneData::with(|data| {
@@@ -667,7 -670,6 +670,6 @@@ pub struct ExpnData 
      /// The kind of this expansion - macro or compiler desugaring.
      pub kind: ExpnKind,
      /// The expansion that produced this expansion.
-     #[stable_hasher(ignore)]
      pub parent: ExpnId,
      /// The location of the actual macro invocation or syntax sugar , e.g.
      /// `let x = foo!();` or `if let Some(y) = x {}`
@@@ -1030,7 -1032,7 +1032,7 @@@ pub fn decode_expn_id
          drop(expns);
          expn_id
      });
 -    return Ok(expn_id);
 +    Ok(expn_id)
  }
  
  // Decodes `SyntaxContext`, using the provided `HygieneDecodeContext`
@@@ -1103,7 -1105,7 +1105,7 @@@ pub fn decode_syntax_context
          assert_eq!(dummy.dollar_crate_name, kw::Invalid);
      });
  
 -    return Ok(new_ctxt);
 +    Ok(new_ctxt)
  }
  
  pub fn num_syntax_ctxts() -> usize {
diff --combined src/librustc_span/lib.rs
index 4c441e1cc71f584a898052eda578e55432aa91ae,ec5cf387b430497a330ea491fdcdfb229bd4c16a..697d88ad0639598ea392fa345260a1eac0749ce0
@@@ -32,8 -32,8 +32,8 @@@ pub mod edition
  use edition::Edition;
  pub mod hygiene;
  pub use hygiene::SyntaxContext;
+ use hygiene::Transparency;
  pub use hygiene::{DesugaringKind, ExpnData, ExpnId, ExpnKind, ForLoopLoc, MacroKind};
- use hygiene::{Transparency, NUM_TRANSPARENCIES};
  pub mod def_id;
  use def_id::{CrateNum, DefId, LOCAL_CRATE};
  mod span_encoding;
@@@ -87,15 -87,6 +87,15 @@@ impl SessionGlobals 
      }
  }
  
 +pub fn with_session_globals<R>(edition: Edition, f: impl FnOnce() -> R) -> R {
 +    let session_globals = SessionGlobals::new(edition);
 +    SESSION_GLOBALS.set(&session_globals, f)
 +}
 +
 +pub fn with_default_session_globals<R>(f: impl FnOnce() -> R) -> R {
 +    with_session_globals(edition::DEFAULT_EDITION, f)
 +}
 +
  // If this ever becomes non thread-local, `decode_syntax_context`
  // and `decode_expn_id` will need to be updated to handle concurrent
  // deserialization.
@@@ -1823,47 -1814,51 +1823,51 @@@ impl<CTX: HashStableContext> HashStable
              TAG_NO_EXPANSION.hash_stable(ctx, hasher);
          } else {
              TAG_EXPANSION.hash_stable(ctx, hasher);
+             let (expn_id, transparency) = self.outer_mark();
+             expn_id.hash_stable(ctx, hasher);
+             transparency.hash_stable(ctx, hasher);
+         }
+     }
+ }
  
-             // Since the same expansion context is usually referenced many
-             // times, we cache a stable hash of it and hash that instead of
-             // recursing every time.
-             thread_local! {
-                 static CACHE: RefCell<Vec<Option<[Option<u64>; NUM_TRANSPARENCIES]>>> = Default::default();
-             }
+ impl<CTX: HashStableContext> HashStable<CTX> for ExpnId {
+     fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
+         // Since the same expansion context is usually referenced many
+         // times, we cache a stable hash of it and hash that instead of
+         // recursing every time.
+         thread_local! {
+             static CACHE: RefCell<Vec<Option<Fingerprint>>> = Default::default();
+         }
  
-             let sub_hash: u64 = CACHE.with(|cache| {
-                 let (expn_id, transparency, _) = self.outer_mark_with_data();
-                 let index = expn_id.as_u32() as usize;
+         const TAG_ROOT: u8 = 0;
+         const TAG_NOT_ROOT: u8 = 1;
  
-                 if let Some(sub_hash_cache) = cache.borrow().get(index).copied().flatten() {
-                     if let Some(sub_hash) = sub_hash_cache[transparency as usize] {
-                         return sub_hash;
-                     }
-                 }
+         if *self == ExpnId::root() {
+             TAG_ROOT.hash_stable(ctx, hasher);
+             return;
+         }
  
-                 let new_len = index + 1;
+         TAG_NOT_ROOT.hash_stable(ctx, hasher);
+         let index = self.as_u32() as usize;
  
-                 let mut hasher = StableHasher::new();
-                 expn_id.expn_data().hash_stable(ctx, &mut hasher);
-                 transparency.hash_stable(ctx, &mut hasher);
+         let res = CACHE.with(|cache| cache.borrow().get(index).copied().flatten());
+         if let Some(res) = res {
+             res.hash_stable(ctx, hasher);
+         } else {
+             let new_len = index + 1;
  
-                 let sub_hash: Fingerprint = hasher.finish();
-                 let sub_hash = sub_hash.to_smaller_hash();
+             let mut sub_hasher = StableHasher::new();
+             self.expn_data().hash_stable(ctx, &mut sub_hasher);
+             let sub_hash: Fingerprint = sub_hasher.finish();
  
+             CACHE.with(|cache| {
                  let mut cache = cache.borrow_mut();
                  if cache.len() < new_len {
                      cache.resize(new_len, None);
                  }
-                 if let Some(mut sub_hash_cache) = cache[index] {
-                     sub_hash_cache[transparency as usize] = Some(sub_hash);
-                 } else {
-                     let mut sub_hash_cache = [None; NUM_TRANSPARENCIES];
-                     sub_hash_cache[transparency as usize] = Some(sub_hash);
-                     cache[index] = Some(sub_hash_cache);
-                 }
-                 sub_hash
+                 cache[index].replace(sub_hash).expect_none("Cache slot was filled");
              });
              sub_hash.hash_stable(ctx, hasher);
          }
      }