Skip to content

Commit 05a4539

Browse files
committed
optimize ctxt setting
1 parent 860db02 commit 05a4539

File tree

3 files changed

+58
-17
lines changed

3 files changed

+58
-17
lines changed

compiler/rustc_expand/src/mbe/transcribe.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ impl MutVisitor for Marker {
3030
// it's some advanced case with macro-generated macros. So if we cache the marked version
3131
// of that context once, we'll typically have a 100% cache hit rate after that.
3232
let Marker(expn_id, transparency, ref mut cache) = *self;
33-
let data = span.data();
34-
let marked_ctxt = *cache
35-
.entry(data.ctxt)
36-
.or_insert_with(|| data.ctxt.apply_mark(expn_id.to_expn_id(), transparency));
37-
*span = data.with_ctxt(marked_ctxt);
33+
span.update_ctxt(|ctxt| {
34+
*cache
35+
.entry(ctxt)
36+
.or_insert_with(|| ctxt.apply_mark(expn_id.to_expn_id(), transparency))
37+
});
3838
}
3939
}
4040

compiler/rustc_span/src/lib.rs

+13-12
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ impl SpanData {
520520
Span::new(self.lo, hi, self.ctxt, self.parent)
521521
}
522522
#[inline]
523-
pub fn with_ctxt(&self, ctxt: SyntaxContext) -> Span {
523+
fn with_ctxt(&self, ctxt: SyntaxContext) -> Span {
524524
Span::new(self.lo, self.hi, ctxt, self.parent)
525525
}
526526
#[inline]
@@ -575,8 +575,9 @@ impl Span {
575575
self.data().with_hi(hi)
576576
}
577577
#[inline]
578-
pub fn with_ctxt(self, ctxt: SyntaxContext) -> Span {
579-
self.data_untracked().with_ctxt(ctxt)
578+
pub fn with_ctxt(mut self, ctxt: SyntaxContext) -> Span {
579+
self.update_ctxt(|_| ctxt);
580+
self
580581
}
581582
#[inline]
582583
pub fn parent(self) -> Option<LocalDefId> {
@@ -1050,9 +1051,9 @@ impl Span {
10501051
}
10511052

10521053
#[inline]
1053-
pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> Span {
1054-
let span = self.data();
1055-
span.with_ctxt(span.ctxt.apply_mark(expn_id, transparency))
1054+
pub fn apply_mark(mut self, expn_id: ExpnId, transparency: Transparency) -> Span {
1055+
self.update_ctxt(|ctxt| ctxt.apply_mark(expn_id, transparency));
1056+
self
10561057
}
10571058

10581059
#[inline]
@@ -1100,15 +1101,15 @@ impl Span {
11001101
}
11011102

11021103
#[inline]
1103-
pub fn normalize_to_macros_2_0(self) -> Span {
1104-
let span = self.data();
1105-
span.with_ctxt(span.ctxt.normalize_to_macros_2_0())
1104+
pub fn normalize_to_macros_2_0(mut self) -> Span {
1105+
self.update_ctxt(|ctxt| ctxt.normalize_to_macros_2_0());
1106+
self
11061107
}
11071108

11081109
#[inline]
1109-
pub fn normalize_to_macro_rules(self) -> Span {
1110-
let span = self.data();
1111-
span.with_ctxt(span.ctxt.normalize_to_macro_rules())
1110+
pub fn normalize_to_macro_rules(mut self) -> Span {
1111+
self.update_ctxt(|ctxt| ctxt.normalize_to_macro_rules());
1112+
self
11121113
}
11131114
}
11141115

compiler/rustc_span/src/span_encoding.rs

+40
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,46 @@ impl Span {
240240
})
241241
}
242242

243+
pub fn update_ctxt(&mut self, update: impl FnOnce(SyntaxContext) -> SyntaxContext) {
244+
let updated_ctxt32;
245+
let data;
246+
if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER {
247+
if self.len_with_tag_or_marker & PARENT_TAG == 0 {
248+
// Inline-context format.
249+
updated_ctxt32 =
250+
update(SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32)).as_u32();
251+
if updated_ctxt32 <= MAX_CTXT {
252+
self.ctxt_or_parent_or_marker = updated_ctxt32 as u16;
253+
return;
254+
}
255+
} else {
256+
// Inline-parent format. We know that the SyntaxContext is root.
257+
updated_ctxt32 = update(SyntaxContext::root()).as_u32();
258+
if updated_ctxt32 == 0 {
259+
// do nothing
260+
return;
261+
}
262+
}
263+
data = self.data_untracked();
264+
} else if self.ctxt_or_parent_or_marker != CTXT_INTERNED_MARKER {
265+
// Partially-interned format. This path avoids looking up the
266+
// interned value, and is the whole point of the
267+
// partially-interned format.
268+
updated_ctxt32 =
269+
update(SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32)).as_u32();
270+
if updated_ctxt32 <= MAX_CTXT {
271+
self.ctxt_or_parent_or_marker = updated_ctxt32 as u16;
272+
return;
273+
}
274+
data = self.data_untracked();
275+
} else {
276+
data = self.data_untracked();
277+
updated_ctxt32 = update(data.ctxt).as_u32();
278+
};
279+
280+
*self = data.with_ctxt(SyntaxContext::from_u32(updated_ctxt32));
281+
}
282+
243283
/// This function is used as a fast path when decoding the full `SpanData` is not necessary.
244284
/// It's a cut-down version of `data_untracked`.
245285
#[cfg_attr(not(test), rustc_diagnostic_item = "SpanCtxt")]

0 commit comments

Comments
 (0)