Skip to content

Commit 0ea65e0

Browse files
committed
Break out some parsing cold functions
This recovers some instruction count regressions after changing most Pat parsing functions return a non-boxed Pat. It seems to be beneficial to break out a #[cold] parsing recovery function when the function includes more parsing, presumably because this requires more stack space and/or mem copies when LLVM optimizes the wrong path.
1 parent 7035846 commit 0ea65e0

File tree

2 files changed

+25
-20
lines changed

2 files changed

+25
-20
lines changed

compiler/rustc_parse/src/parser/diagnostics.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,15 +1845,17 @@ impl<'a> Parser<'a> {
18451845
&mut self,
18461846
base: T,
18471847
) -> PResult<'a, T> {
1848-
if !self.may_recover() {
1849-
return Ok(base);
1848+
// Do not add `::` to expected tokens.
1849+
if self.may_recover() && self.token == token::PathSep {
1850+
return self.recover_from_bad_qpath(base);
18501851
}
1852+
Ok(base)
1853+
}
18511854

1852-
// Do not add `::` to expected tokens.
1853-
if self.token == token::PathSep {
1854-
if let Some(ty) = base.to_ty() {
1855-
return self.maybe_recover_from_bad_qpath_stage_2(ty.span, ty);
1856-
}
1855+
#[cold]
1856+
fn recover_from_bad_qpath<T: RecoverQPath>(&mut self, base: T) -> PResult<'a, T> {
1857+
if let Some(ty) = base.to_ty() {
1858+
return self.maybe_recover_from_bad_qpath_stage_2(ty.span, ty);
18571859
}
18581860
Ok(base)
18591861
}
@@ -2370,6 +2372,7 @@ impl<'a> Parser<'a> {
23702372
None
23712373
}
23722374

2375+
#[cold]
23732376
pub(super) fn recover_arg_parse(&mut self) -> PResult<'a, (Box<ast::Pat>, Box<ast::Ty>)> {
23742377
let pat = self.parse_pat_no_top_alt(Some(Expected::ArgumentName), None)?;
23752378
self.expect(exp!(Colon))?;
@@ -2750,7 +2753,8 @@ impl<'a> Parser<'a> {
27502753

27512754
/// Some special error handling for the "top-level" patterns in a match arm,
27522755
/// `for` loop, `let`, &c. (in contrast to subpatterns within such).
2753-
pub(crate) fn maybe_recover_colon_colon_in_pat_typo(
2756+
#[cold]
2757+
pub(crate) fn recover_colon_colon_in_pat_typo(
27542758
&mut self,
27552759
mut first_pat: Pat,
27562760
expected: Option<Expected>,
@@ -2935,7 +2939,11 @@ impl<'a> Parser<'a> {
29352939
if self.token != token::Comma {
29362940
return Ok(());
29372941
}
2942+
self.recover_unexpected_comma(lo, rt)
2943+
}
29382944

2945+
#[cold]
2946+
fn recover_unexpected_comma(&mut self, lo: Span, rt: CommaRecoveryMode) -> PResult<'a, ()> {
29392947
// An unexpected comma after a top-level pattern is a clue that the
29402948
// user (perhaps more accustomed to some other language) forgot the
29412949
// parentheses in what should have been a tuple pattern; return a

compiler/rustc_parse/src/parser/pat.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,8 @@ impl<'a> Parser<'a> {
199199
// This complicated procedure is done purely for diagnostics UX.
200200

201201
// Check if the user wrote `foo:bar` instead of `foo::bar`.
202-
if ra == RecoverColon::Yes {
203-
first_pat = self.maybe_recover_colon_colon_in_pat_typo(first_pat, expected);
202+
if ra == RecoverColon::Yes && token::Colon == self.token.kind {
203+
first_pat = self.recover_colon_colon_in_pat_typo(first_pat, expected);
204204
}
205205

206206
if let Some(leading_vert_span) = leading_vert_span {
@@ -874,9 +874,12 @@ impl<'a> Parser<'a> {
874874
}
875875
};
876876

877-
let pat = self.mk_pat(lo.to(self.prev_token.span), pat);
878-
let pat = self.maybe_recover_from_bad_qpath(pat)?;
879-
let pat = self.recover_intersection_pat(pat)?;
877+
let mut pat = self.mk_pat(lo.to(self.prev_token.span), pat);
878+
879+
pat = self.maybe_recover_from_bad_qpath(pat)?;
880+
if self.eat_noexpect(&token::At) {
881+
pat = self.recover_intersection_pat(pat)?;
882+
}
880883

881884
if !allow_range_pat {
882885
self.ban_pat_range_if_ambiguous(&pat)
@@ -922,14 +925,8 @@ impl<'a> Parser<'a> {
922925
/// e.g. [F#][and] where they are called AND-patterns.
923926
///
924927
/// [and]: https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching
928+
#[cold]
925929
fn recover_intersection_pat(&mut self, lhs: Pat) -> PResult<'a, Pat> {
926-
if self.token != token::At {
927-
// Next token is not `@` so it's not going to be an intersection pattern.
928-
return Ok(lhs);
929-
}
930-
931-
// At this point we attempt to parse `@ $pat_rhs` and emit an error.
932-
self.bump(); // `@`
933930
let mut rhs = self.parse_pat_no_top_alt(None, None)?;
934931
let whole_span = lhs.span.to(rhs.span);
935932

0 commit comments

Comments
 (0)