Skip to content

Commit 828f6fd

Browse files
committed
Introduce and use Mark::outer_is_descendant_of().
It reduces two `hygiene_data` accesses to one on some hot paths.
1 parent 7212685 commit 828f6fd

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

src/librustc_resolve/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2308,7 +2308,7 @@ impl<'a> Resolver<'a> {
23082308

23092309
fn hygienic_lexical_parent(&mut self, module: Module<'a>, span: &mut Span)
23102310
-> Option<Module<'a>> {
2311-
if !module.expansion.is_descendant_of(span.ctxt().outer()) {
2311+
if !module.expansion.outer_is_descendant_of(span.ctxt()) {
23122312
return Some(self.macro_def_scope(span.remove_mark()));
23132313
}
23142314

@@ -2344,7 +2344,7 @@ impl<'a> Resolver<'a> {
23442344
module.expansion.is_descendant_of(parent.expansion) {
23452345
// The macro is a proc macro derive
23462346
if module.expansion.looks_like_proc_macro_derive() {
2347-
if parent.expansion.is_descendant_of(span.ctxt().outer()) {
2347+
if parent.expansion.outer_is_descendant_of(span.ctxt()) {
23482348
*poisoned = Some(node_id);
23492349
return module.parent;
23502350
}

src/libsyntax_pos/hygiene.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)