mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 23:12:02 +00:00
parser: move maybe_recover_unexpected_comma
to a more appropriate place.
This commit is contained in:
parent
6498959377
commit
39f5e5bec4
@ -35,62 +35,12 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper around `parse_pat` with some special error handling for the
|
||||
/// "top-level" patterns in a match arm, `for` loop, `let`, &c. (in contrast
|
||||
/// to subpatterns within such).
|
||||
pub(super) fn parse_top_level_pat(&mut self) -> PResult<'a, P<Pat>> {
|
||||
let pat = self.parse_pat(None)?;
|
||||
self.maybe_recover_unexpected_comma(pat.span, true)?;
|
||||
Ok(pat)
|
||||
}
|
||||
|
||||
fn maybe_recover_unexpected_comma(&mut self, lo: Span, top_level: bool) -> PResult<'a, ()> {
|
||||
if !top_level || self.token != token::Comma {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// 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
|
||||
// suggestion-enhanced error here rather than choking on the comma later.
|
||||
let comma_span = self.token.span;
|
||||
self.bump();
|
||||
if let Err(mut err) = self.skip_pat_list() {
|
||||
// We didn't expect this to work anyway; we just wanted to advance to the
|
||||
// end of the comma-sequence so we know the span to suggest parenthesizing.
|
||||
err.cancel();
|
||||
}
|
||||
let seq_span = lo.to(self.prev_span);
|
||||
let mut err = self.struct_span_err(comma_span, "unexpected `,` in pattern");
|
||||
if let Ok(seq_snippet) = self.span_to_snippet(seq_span) {
|
||||
err.span_suggestion(
|
||||
seq_span,
|
||||
"try adding parentheses to match on a tuple..",
|
||||
format!("({})", seq_snippet),
|
||||
Applicability::MachineApplicable
|
||||
)
|
||||
.span_suggestion(
|
||||
seq_span,
|
||||
"..or a vertical bar to match on multiple alternatives",
|
||||
format!("{}", seq_snippet.replace(",", " |")),
|
||||
Applicability::MachineApplicable
|
||||
);
|
||||
}
|
||||
Err(err)
|
||||
}
|
||||
|
||||
/// Parse and throw away a parentesized comma separated
|
||||
/// sequence of patterns until `)` is reached.
|
||||
fn skip_pat_list(&mut self) -> PResult<'a, ()> {
|
||||
while !self.check(&token::CloseDelim(token::Paren)) {
|
||||
self.parse_pat(None)?;
|
||||
if !self.eat(&token::Comma) {
|
||||
return Ok(())
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parses a pattern, that may be a or-pattern (e.g. `Foo | Bar` in `Some(Foo | Bar)`).
|
||||
/// Corresponds to `pat<allow_top_alt>` in RFC 2535.
|
||||
fn parse_pat_with_or(
|
||||
@ -151,6 +101,55 @@ impl<'a> Parser<'a> {
|
||||
.emit();
|
||||
}
|
||||
|
||||
/// Some special error handling for the "top-level" patterns in a match arm,
|
||||
/// `for` loop, `let`, &c. (in contrast to subpatterns within such).
|
||||
fn maybe_recover_unexpected_comma(&mut self, lo: Span, top_level: bool) -> PResult<'a, ()> {
|
||||
if !top_level || self.token != token::Comma {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// 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
|
||||
// suggestion-enhanced error here rather than choking on the comma later.
|
||||
let comma_span = self.token.span;
|
||||
self.bump();
|
||||
if let Err(mut err) = self.skip_pat_list() {
|
||||
// We didn't expect this to work anyway; we just wanted to advance to the
|
||||
// end of the comma-sequence so we know the span to suggest parenthesizing.
|
||||
err.cancel();
|
||||
}
|
||||
let seq_span = lo.to(self.prev_span);
|
||||
let mut err = self.struct_span_err(comma_span, "unexpected `,` in pattern");
|
||||
if let Ok(seq_snippet) = self.span_to_snippet(seq_span) {
|
||||
err.span_suggestion(
|
||||
seq_span,
|
||||
"try adding parentheses to match on a tuple..",
|
||||
format!("({})", seq_snippet),
|
||||
Applicability::MachineApplicable
|
||||
)
|
||||
.span_suggestion(
|
||||
seq_span,
|
||||
"..or a vertical bar to match on multiple alternatives",
|
||||
format!("{}", seq_snippet.replace(",", " |")),
|
||||
Applicability::MachineApplicable
|
||||
);
|
||||
}
|
||||
Err(err)
|
||||
}
|
||||
|
||||
/// Parse and throw away a parentesized comma separated
|
||||
/// sequence of patterns until `)` is reached.
|
||||
fn skip_pat_list(&mut self) -> PResult<'a, ()> {
|
||||
while !self.check(&token::CloseDelim(token::Paren)) {
|
||||
self.parse_pat(None)?;
|
||||
if !self.eat(&token::Comma) {
|
||||
return Ok(())
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are
|
||||
/// allowed).
|
||||
fn parse_pat_with_range_pat(
|
||||
|
Loading…
Reference in New Issue
Block a user