parser: better recovery for || in inner pats.
This commit is contained in:
parent
1ffea18ddb
commit
b205055c7b
3 changed files with 93 additions and 44 deletions
|
|
@ -155,6 +155,25 @@ impl<'a> Parser<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Recursive possibly-or-pattern parser with recovery for an erroneous leading `|`.
|
||||
/// See `parse_pat_with_or` for details on parsing or-patterns.
|
||||
fn parse_pat_with_or_inner(&mut self, expected: Expected) -> PResult<'a, P<Pat>> {
|
||||
// Recover if `|` or `||` is here.
|
||||
// The user is thinking that a leading `|` is allowed in this position.
|
||||
if let token::BinOp(token::Or) | token::OrOr = self.token.kind {
|
||||
let span = self.token.span;
|
||||
let rm_msg = format!("remove the `{}`", pprust::token_to_string(&self.token));
|
||||
|
||||
self.struct_span_err(span, "a leading `|` is only allowed in a top-level pattern")
|
||||
.span_suggestion(span, &rm_msg, String::new(), Applicability::MachineApplicable)
|
||||
.emit();
|
||||
|
||||
self.bump();
|
||||
}
|
||||
|
||||
self.parse_pat_with_or(expected, true, false)
|
||||
}
|
||||
|
||||
/// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are
|
||||
/// allowed).
|
||||
fn parse_pat_with_range_pat(
|
||||
|
|
@ -173,7 +192,7 @@ impl<'a> Parser<'a> {
|
|||
// Parse `[pat, pat,...]` as a slice pattern.
|
||||
let (pats, _) = self.parse_delim_comma_seq(
|
||||
token::Bracket,
|
||||
|p| p.parse_pat_with_or(None, true, false),
|
||||
|p| p.parse_pat_with_or_inner(None),
|
||||
)?;
|
||||
PatKind::Slice(pats)
|
||||
}
|
||||
|
|
@ -303,7 +322,7 @@ impl<'a> Parser<'a> {
|
|||
/// Parse a tuple or parenthesis pattern.
|
||||
fn parse_pat_tuple_or_parens(&mut self) -> PResult<'a, PatKind> {
|
||||
let (fields, trailing_comma) = self.parse_paren_comma_seq(|p| {
|
||||
p.parse_pat_with_or(None, true, false)
|
||||
p.parse_pat_with_or_inner(None)
|
||||
})?;
|
||||
|
||||
// Here, `(pat,)` is a tuple pattern.
|
||||
|
|
@ -547,7 +566,7 @@ impl<'a> Parser<'a> {
|
|||
err.span_label(self.token.span, msg);
|
||||
return Err(err);
|
||||
}
|
||||
let (fields, _) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or(None, true, false))?;
|
||||
let (fields, _) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or_inner(None))?;
|
||||
Ok(PatKind::TupleStruct(path, fields))
|
||||
}
|
||||
|
||||
|
|
@ -691,7 +710,7 @@ impl<'a> Parser<'a> {
|
|||
// Parsing a pattern of the form "fieldname: pat"
|
||||
let fieldname = self.parse_field_name()?;
|
||||
self.bump();
|
||||
let pat = self.parse_pat_with_or(None, true, false)?;
|
||||
let pat = self.parse_pat_with_or_inner(None)?;
|
||||
hi = pat.span;
|
||||
(pat, fieldname, false)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -30,27 +30,20 @@ fn no_top_level_or_patterns() {
|
|||
|
||||
// We also do not allow a leading `|` when not in a top level position:
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn no_leading_parens() {
|
||||
let ( | A | B); //~ ERROR expected pattern, found `|`
|
||||
}
|
||||
fn no_leading_inner() {
|
||||
struct TS(E);
|
||||
struct NS { f: E }
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn no_leading_tuple() {
|
||||
let ( | A | B,); //~ ERROR expected pattern, found `|`
|
||||
}
|
||||
let ( | A | B) = E::A; //~ ERROR a leading `|` is only allowed in a top-level pattern
|
||||
let ( | A | B,) = (E::B,); //~ ERROR a leading `|` is only allowed in a top-level pattern
|
||||
let [ | A | B ] = [E::A]; //~ ERROR a leading `|` is only allowed in a top-level pattern
|
||||
let TS( | A | B ); //~ ERROR a leading `|` is only allowed in a top-level pattern
|
||||
let NS { f: | A | B }; //~ ERROR a leading `|` is only allowed in a top-level pattern
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn no_leading_slice() {
|
||||
let [ | A | B ]; //~ ERROR expected pattern, found `|`
|
||||
}
|
||||
let ( || A | B) = E::A; //~ ERROR a leading `|` is only allowed in a top-level pattern
|
||||
let [ || A | B ] = [E::A]; //~ ERROR a leading `|` is only allowed in a top-level pattern
|
||||
let TS( || A | B ); //~ ERROR a leading `|` is only allowed in a top-level pattern
|
||||
let NS { f: || A | B }; //~ ERROR a leading `|` is only allowed in a top-level pattern
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn no_leading_tuple_struct() {
|
||||
let TS( | A | B ); //~ ERROR expected pattern, found `|`
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn no_leading_struct() {
|
||||
let NS { f: | A | B }; //~ ERROR expected pattern, found `|`
|
||||
let recovery_witness: String = 0; //~ ERROR mismatched types
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,35 +4,59 @@ error: expected one of `:` or `@`, found `|`
|
|||
LL | fn fun(A | B: E) {}
|
||||
| ^ expected one of `:` or `@` here
|
||||
|
||||
error: expected pattern, found `|`
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:35:11
|
||||
error: a leading `|` is only allowed in a top-level pattern
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:37:11
|
||||
|
|
||||
LL | let ( | A | B);
|
||||
| ^ expected pattern
|
||||
LL | let ( | A | B) = E::A;
|
||||
| ^ help: remove the `|`
|
||||
|
||||
error: expected pattern, found `|`
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:40:11
|
||||
error: a leading `|` is only allowed in a top-level pattern
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:38:11
|
||||
|
|
||||
LL | let ( | A | B,);
|
||||
| ^ expected pattern
|
||||
LL | let ( | A | B,) = (E::B,);
|
||||
| ^ help: remove the `|`
|
||||
|
||||
error: expected pattern, found `|`
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:45:11
|
||||
error: a leading `|` is only allowed in a top-level pattern
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:39:11
|
||||
|
|
||||
LL | let [ | A | B ];
|
||||
| ^ expected pattern
|
||||
LL | let [ | A | B ] = [E::A];
|
||||
| ^ help: remove the `|`
|
||||
|
||||
error: expected pattern, found `|`
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:50:13
|
||||
error: a leading `|` is only allowed in a top-level pattern
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:40:13
|
||||
|
|
||||
LL | let TS( | A | B );
|
||||
| ^ expected pattern
|
||||
| ^ help: remove the `|`
|
||||
|
||||
error: expected pattern, found `|`
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:55:17
|
||||
error: a leading `|` is only allowed in a top-level pattern
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:41:17
|
||||
|
|
||||
LL | let NS { f: | A | B };
|
||||
| ^ expected pattern
|
||||
| ^ help: remove the `|`
|
||||
|
||||
error: a leading `|` is only allowed in a top-level pattern
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:43:11
|
||||
|
|
||||
LL | let ( || A | B) = E::A;
|
||||
| ^^ help: remove the `||`
|
||||
|
||||
error: a leading `|` is only allowed in a top-level pattern
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:44:11
|
||||
|
|
||||
LL | let [ || A | B ] = [E::A];
|
||||
| ^^ help: remove the `||`
|
||||
|
||||
error: a leading `|` is only allowed in a top-level pattern
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:45:13
|
||||
|
|
||||
LL | let TS( || A | B );
|
||||
| ^^ help: remove the `||`
|
||||
|
||||
error: a leading `|` is only allowed in a top-level pattern
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:46:17
|
||||
|
|
||||
LL | let NS { f: || A | B };
|
||||
| ^^ help: remove the `||`
|
||||
|
||||
error: no rules expected the token `|`
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:14:15
|
||||
|
|
@ -70,6 +94,19 @@ LL | let _ = |A | B: E| ();
|
|||
|
|
||||
= note: an implementation of `std::ops::BitOr` might be missing for `E`
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:48:36
|
||||
|
|
||||
LL | let recovery_witness: String = 0;
|
||||
| ^
|
||||
| |
|
||||
| expected struct `std::string::String`, found integer
|
||||
| help: try using a conversion method: `0.to_string()`
|
||||
|
|
||||
= note: expected type `std::string::String`
|
||||
found type `{integer}`
|
||||
|
||||
For more information about this error, try `rustc --explain E0369`.
|
||||
error: aborting due to 14 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0369.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue