about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-11-29 07:46:36 +0000
committerbors <bors@rust-lang.org>2021-11-29 07:46:36 +0000
commit44723c5d59ff00daeefbf2a01f67089acd75730d (patch)
tree4c9dcce8146840b8bc2b793055558d707a32ac54
parent9981e56d3b820f429fac62b4ff916f2a871340b4 (diff)
parentac8d514376c70cbb78e42354ddddc3f2534961ae (diff)
downloadrust-44723c5d59ff00daeefbf2a01f67089acd75730d.tar.gz
rust-44723c5d59ff00daeefbf2a01f67089acd75730d.zip
Auto merge of #91043 - camsteffen:descendant-eq, r=petrochenkov
Add fast path to `is_descendant_of`
-rw-r--r--compiler/rustc_span/src/hygiene.rs22
1 files changed, 20 insertions, 2 deletions
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index d590776676b..315b706fbc4 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -264,7 +264,15 @@ impl ExpnId {
         HygieneData::with(|data| data.expn_data(self).clone())
     }
 
+    #[inline]
     pub fn is_descendant_of(self, ancestor: ExpnId) -> bool {
+        // a few "fast path" cases to avoid locking HygieneData
+        if ancestor == ExpnId::root() || ancestor == self {
+            return true;
+        }
+        if ancestor.krate != self.krate {
+            return false;
+        }
         HygieneData::with(|data| data.is_descendant_of(self, ancestor))
     }
 
@@ -376,13 +384,22 @@ impl HygieneData {
     }
 
     fn is_descendant_of(&self, mut expn_id: ExpnId, ancestor: ExpnId) -> bool {
-        while expn_id != ancestor {
+        // a couple "fast path" cases to avoid traversing parents in the loop below
+        if ancestor == ExpnId::root() {
+            return true;
+        }
+        if expn_id.krate != ancestor.krate {
+            return false;
+        }
+        loop {
+            if expn_id == ancestor {
+                return true;
+            }
             if expn_id == ExpnId::root() {
                 return false;
             }
             expn_id = self.expn_data(expn_id).parent;
         }
-        true
     }
 
     fn normalize_to_macros_2_0(&self, ctxt: SyntaxContext) -> SyntaxContext {
@@ -1223,6 +1240,7 @@ pub fn register_expn_id(
     data: ExpnData,
     hash: ExpnHash,
 ) -> ExpnId {
+    debug_assert!(data.parent == ExpnId::root() || krate == data.parent.krate);
     let expn_id = ExpnId { krate, local_id };
     HygieneData::with(|hygiene_data| {
         let _old_data = hygiene_data.foreign_expn_data.insert(expn_id, data);