Recover parser from foo(_, _)
This commit is contained in:
parent
195d837f18
commit
b7f7756566
@ -2052,9 +2052,23 @@ impl<'a> Parser<'a> {
|
||||
while self.token != token::CloseDelim(token::Paren) {
|
||||
es.push(match self.parse_expr() {
|
||||
Ok(es) => es,
|
||||
Err(err) => {
|
||||
Err(mut err) => {
|
||||
// recover from parse error in tuple list
|
||||
return Ok(self.recover_seq_parse_error(token::Paren, lo, Err(err)));
|
||||
match self.token.kind {
|
||||
token::Ident(name, false)
|
||||
if name == kw::Underscore && self.look_ahead(1, |t| {
|
||||
t == &token::Comma
|
||||
}) => {
|
||||
// Special-case handling of `Foo<(_, _, _)>`
|
||||
err.emit();
|
||||
let sp = self.token.span;
|
||||
self.bump();
|
||||
self.mk_expr(sp, ExprKind::Err, ThinVec::new())
|
||||
}
|
||||
_ => return Ok(
|
||||
self.recover_seq_parse_error(token::Paren, lo, Err(err)),
|
||||
),
|
||||
}
|
||||
}
|
||||
});
|
||||
recovered = self.expect_one_of(
|
||||
@ -2456,9 +2470,10 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
/// Parses `a.b` or `a(13)` or `a[4]` or just `a`.
|
||||
fn parse_dot_or_call_expr(&mut self,
|
||||
already_parsed_attrs: Option<ThinVec<Attribute>>)
|
||||
-> PResult<'a, P<Expr>> {
|
||||
fn parse_dot_or_call_expr(
|
||||
&mut self,
|
||||
already_parsed_attrs: Option<ThinVec<Attribute>>,
|
||||
) -> PResult<'a, P<Expr>> {
|
||||
let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
|
||||
|
||||
let b = self.parse_bottom_expr();
|
||||
@ -2466,16 +2481,16 @@ impl<'a> Parser<'a> {
|
||||
self.parse_dot_or_call_expr_with(b, span, attrs)
|
||||
}
|
||||
|
||||
fn parse_dot_or_call_expr_with(&mut self,
|
||||
e0: P<Expr>,
|
||||
lo: Span,
|
||||
mut attrs: ThinVec<Attribute>)
|
||||
-> PResult<'a, P<Expr>> {
|
||||
fn parse_dot_or_call_expr_with(
|
||||
&mut self,
|
||||
e0: P<Expr>,
|
||||
lo: Span,
|
||||
mut attrs: ThinVec<Attribute>,
|
||||
) -> PResult<'a, P<Expr>> {
|
||||
// Stitch the list of outer attributes onto the return value.
|
||||
// A little bit ugly, but the best way given the current code
|
||||
// structure
|
||||
self.parse_dot_or_call_expr_with_(e0, lo)
|
||||
.map(|expr|
|
||||
self.parse_dot_or_call_expr_with_(e0, lo).map(|expr|
|
||||
expr.map(|mut expr| {
|
||||
attrs.extend::<Vec<_>>(expr.attrs.into());
|
||||
expr.attrs = attrs;
|
||||
@ -2483,10 +2498,7 @@ impl<'a> Parser<'a> {
|
||||
ExprKind::If(..) if !expr.attrs.is_empty() => {
|
||||
// Just point to the first attribute in there...
|
||||
let span = expr.attrs[0].span;
|
||||
|
||||
self.span_err(span,
|
||||
"attributes are not yet allowed on `if` \
|
||||
expressions");
|
||||
self.span_err(span, "attributes are not yet allowed on `if` expressions");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -2624,7 +2636,24 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
fn parse_paren_expr_seq(&mut self) -> PResult<'a, Vec<P<Expr>>> {
|
||||
self.parse_paren_comma_seq(|p| p.parse_expr()).map(|(r, _)| r)
|
||||
self.parse_paren_comma_seq(|p| {
|
||||
match p.parse_expr() {
|
||||
Ok(expr) => Ok(expr),
|
||||
Err(mut err) => match p.token.kind {
|
||||
token::Ident(name, false)
|
||||
if name == kw::Underscore && p.look_ahead(1, |t| {
|
||||
t == &token::Comma
|
||||
}) => {
|
||||
// Special-case handling of `foo(_, _, _)`
|
||||
err.emit();
|
||||
let sp = p.token.span;
|
||||
p.bump();
|
||||
Ok(p.mk_expr(sp, ExprKind::Err, ThinVec::new()))
|
||||
}
|
||||
_ => Err(err),
|
||||
},
|
||||
}
|
||||
}).map(|(r, _)| r)
|
||||
}
|
||||
|
||||
crate fn process_potential_macro_variable(&mut self) {
|
||||
@ -2806,9 +2835,10 @@ impl<'a> Parser<'a> {
|
||||
/// This parses an expression accounting for associativity and precedence of the operators in
|
||||
/// the expression.
|
||||
#[inline]
|
||||
fn parse_assoc_expr(&mut self,
|
||||
already_parsed_attrs: Option<ThinVec<Attribute>>)
|
||||
-> PResult<'a, P<Expr>> {
|
||||
fn parse_assoc_expr(
|
||||
&mut self,
|
||||
already_parsed_attrs: Option<ThinVec<Attribute>>,
|
||||
) -> PResult<'a, P<Expr>> {
|
||||
self.parse_assoc_expr_with(0, already_parsed_attrs.into())
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ fn main () {
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR invalid left-hand side expression
|
||||
//~| ERROR expected expression, found reserved identifier `_`
|
||||
//~| ERROR expected expression, found reserved identifier `_`
|
||||
let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
|
||||
//~^ ERROR no method named `iter` found for type `()` in the current scope
|
||||
}
|
||||
|
@ -4,6 +4,12 @@ error: expected expression, found reserved identifier `_`
|
||||
LL | let sr: Vec<(u32, _, _) = vec![];
|
||||
| ^ expected expression
|
||||
|
||||
error: expected expression, found reserved identifier `_`
|
||||
--> $DIR/issue-34334.rs:2:26
|
||||
|
|
||||
LL | let sr: Vec<(u32, _, _) = vec![];
|
||||
| ^ expected expression
|
||||
|
||||
error: expected one of `,` or `>`, found `=`
|
||||
--> $DIR/issue-34334.rs:2:29
|
||||
|
|
||||
@ -36,12 +42,12 @@ LL | let sr: Vec<(u32, _, _) = vec![];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ left-hand of expression not valid
|
||||
|
||||
error[E0599]: no method named `iter` found for type `()` in the current scope
|
||||
--> $DIR/issue-34334.rs:8:36
|
||||
--> $DIR/issue-34334.rs:9:36
|
||||
|
|
||||
LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0070, E0308, E0423, E0599.
|
||||
For more information about an error, try `rustc --explain E0070`.
|
||||
|
@ -0,0 +1,19 @@
|
||||
fn foo(a: usize, b: usize) -> usize { a }
|
||||
|
||||
struct S(usize, usize);
|
||||
|
||||
trait T {
|
||||
fn baz(x: usize, y: usize) -> usize { x }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _: usize = foo(_, _);
|
||||
//~^ ERROR expected expression
|
||||
//~| ERROR expected expression
|
||||
let _: S = S(_, _);
|
||||
//~^ ERROR expected expression
|
||||
//~| ERROR expected expression
|
||||
let _: usize = T::baz(_, _);
|
||||
//~^ ERROR expected expression
|
||||
//~| ERROR expected expression
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
error: expected expression, found reserved identifier `_`
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:24
|
||||
|
|
||||
LL | let _: usize = foo(_, _);
|
||||
| ^ expected expression
|
||||
|
||||
error: expected expression, found reserved identifier `_`
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:27
|
||||
|
|
||||
LL | let _: usize = foo(_, _);
|
||||
| ^ expected expression
|
||||
|
||||
error: expected expression, found reserved identifier `_`
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:13:18
|
||||
|
|
||||
LL | let _: S = S(_, _);
|
||||
| ^ expected expression
|
||||
|
||||
error: expected expression, found reserved identifier `_`
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:13:21
|
||||
|
|
||||
LL | let _: S = S(_, _);
|
||||
| ^ expected expression
|
||||
|
||||
error: expected expression, found reserved identifier `_`
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:16:27
|
||||
|
|
||||
LL | let _: usize = T::baz(_, _);
|
||||
| ^ expected expression
|
||||
|
||||
error: expected expression, found reserved identifier `_`
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:16:30
|
||||
|
|
||||
LL | let _: usize = T::baz(_, _);
|
||||
| ^ expected expression
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
Loading…
x
Reference in New Issue
Block a user