@@ -124,6 +124,21 @@ impl Mark {
124124 } )
125125 }
126126
127+ /// `mark.outer_is_descendant_of(ctxt)` is equivalent to but faster than
128+ /// `mark.is_descendant_of(ctxt.outer())`.
129+ pub fn outer_is_descendant_of ( mut self , ctxt : SyntaxContext ) -> bool {
130+ HygieneData :: with ( |data| {
131+ let outer = data. syntax_contexts [ ctxt. 0 as usize ] . outer_mark ;
132+ while self != outer {
133+ if self == Mark :: root ( ) {
134+ return false ;
135+ }
136+ self = data. marks [ self . 0 as usize ] . parent ;
137+ }
138+ true
139+ } )
140+ }
141+
127142 /// Computes a mark such that both input marks are descendants of (or equal to) the returned
128143 /// mark. That is, the following holds:
129144 ///
@@ -416,7 +431,7 @@ impl SyntaxContext {
416431 /// or `None` if we privacy check as usual (i.e., not w.r.t. a macro definition scope).
417432 pub fn adjust ( & mut self , expansion : Mark ) -> Option < Mark > {
418433 let mut scope = None ;
419- while !expansion. is_descendant_of ( self . outer ( ) ) {
434+ while !expansion. outer_is_descendant_of ( * self ) {
420435 scope = Some ( self . remove_mark ( ) ) ;
421436 }
422437 scope
@@ -450,7 +465,7 @@ impl SyntaxContext {
450465 pub fn glob_adjust ( & mut self , expansion : Mark , mut glob_ctxt : SyntaxContext )
451466 -> Option < Option < Mark > > {
452467 let mut scope = None ;
453- while !expansion. is_descendant_of ( glob_ctxt. outer ( ) ) {
468+ while !expansion. outer_is_descendant_of ( glob_ctxt) {
454469 scope = Some ( glob_ctxt. remove_mark ( ) ) ;
455470 if self . remove_mark ( ) != scope. unwrap ( ) {
456471 return None ;
@@ -476,7 +491,7 @@ impl SyntaxContext {
476491 }
477492
478493 let mut marks = Vec :: new ( ) ;
479- while !expansion. is_descendant_of ( glob_ctxt. outer ( ) ) {
494+ while !expansion. outer_is_descendant_of ( glob_ctxt) {
480495 marks. push ( glob_ctxt. remove_mark ( ) ) ;
481496 }
482497
0 commit comments