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.
This commit is contained in:
@@ -1845,15 +1845,17 @@ impl<'a> Parser<'a> {
|
||||
&mut self,
|
||||
base: T,
|
||||
) -> PResult<'a, T> {
|
||||
if !self.may_recover() {
|
||||
return Ok(base);
|
||||
}
|
||||
|
||||
// Do not add `::` to expected tokens.
|
||||
if self.token == token::PathSep {
|
||||
if let Some(ty) = base.to_ty() {
|
||||
return self.maybe_recover_from_bad_qpath_stage_2(ty.span, ty);
|
||||
}
|
||||
if self.may_recover() && self.token == token::PathSep {
|
||||
return self.recover_from_bad_qpath(base);
|
||||
}
|
||||
Ok(base)
|
||||
}
|
||||
|
||||
#[cold]
|
||||
fn recover_from_bad_qpath<T: RecoverQPath>(&mut self, base: T) -> PResult<'a, T> {
|
||||
if let Some(ty) = base.to_ty() {
|
||||
return self.maybe_recover_from_bad_qpath_stage_2(ty.span, ty);
|
||||
}
|
||||
Ok(base)
|
||||
}
|
||||
@@ -2370,6 +2372,7 @@ impl<'a> Parser<'a> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cold]
|
||||
pub(super) fn recover_arg_parse(&mut self) -> PResult<'a, (Box<ast::Pat>, Box<ast::Ty>)> {
|
||||
let pat = self.parse_pat_no_top_alt(Some(Expected::ArgumentName), None)?;
|
||||
self.expect(exp!(Colon))?;
|
||||
@@ -2750,7 +2753,8 @@ impl<'a> Parser<'a> {
|
||||
|
||||
/// Some special error handling for the "top-level" patterns in a match arm,
|
||||
/// `for` loop, `let`, &c. (in contrast to subpatterns within such).
|
||||
pub(crate) fn maybe_recover_colon_colon_in_pat_typo(
|
||||
#[cold]
|
||||
pub(crate) fn recover_colon_colon_in_pat_typo(
|
||||
&mut self,
|
||||
mut first_pat: Pat,
|
||||
expected: Option<Expected>,
|
||||
@@ -2935,7 +2939,11 @@ impl<'a> Parser<'a> {
|
||||
if self.token != token::Comma {
|
||||
return Ok(());
|
||||
}
|
||||
self.recover_unexpected_comma(lo, rt)
|
||||
}
|
||||
|
||||
#[cold]
|
||||
fn recover_unexpected_comma(&mut self, lo: Span, rt: CommaRecoveryMode) -> PResult<'a, ()> {
|
||||
// An unexpected comma after a top-level pattern is a clue that the
|
||||
// user (perhaps more accustomed to some other language) forgot the
|
||||
// parentheses in what should have been a tuple pattern; return a
|
||||
|
||||
@@ -199,8 +199,8 @@ impl<'a> Parser<'a> {
|
||||
// This complicated procedure is done purely for diagnostics UX.
|
||||
|
||||
// Check if the user wrote `foo:bar` instead of `foo::bar`.
|
||||
if ra == RecoverColon::Yes {
|
||||
first_pat = self.maybe_recover_colon_colon_in_pat_typo(first_pat, expected);
|
||||
if ra == RecoverColon::Yes && token::Colon == self.token.kind {
|
||||
first_pat = self.recover_colon_colon_in_pat_typo(first_pat, expected);
|
||||
}
|
||||
|
||||
if let Some(leading_vert_span) = leading_vert_span {
|
||||
@@ -874,9 +874,12 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
};
|
||||
|
||||
let pat = self.mk_pat(lo.to(self.prev_token.span), pat);
|
||||
let pat = self.maybe_recover_from_bad_qpath(pat)?;
|
||||
let pat = self.recover_intersection_pat(pat)?;
|
||||
let mut pat = self.mk_pat(lo.to(self.prev_token.span), pat);
|
||||
|
||||
pat = self.maybe_recover_from_bad_qpath(pat)?;
|
||||
if self.eat_noexpect(&token::At) {
|
||||
pat = self.recover_intersection_pat(pat)?;
|
||||
}
|
||||
|
||||
if !allow_range_pat {
|
||||
self.ban_pat_range_if_ambiguous(&pat)
|
||||
@@ -922,14 +925,8 @@ impl<'a> Parser<'a> {
|
||||
/// e.g. [F#][and] where they are called AND-patterns.
|
||||
///
|
||||
/// [and]: https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching
|
||||
#[cold]
|
||||
fn recover_intersection_pat(&mut self, lhs: Pat) -> PResult<'a, Pat> {
|
||||
if self.token != token::At {
|
||||
// Next token is not `@` so it's not going to be an intersection pattern.
|
||||
return Ok(lhs);
|
||||
}
|
||||
|
||||
// At this point we attempt to parse `@ $pat_rhs` and emit an error.
|
||||
self.bump(); // `@`
|
||||
let mut rhs = self.parse_pat_no_top_alt(None, None)?;
|
||||
let whole_span = lhs.span.to(rhs.span);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user