Tweak field parse error recovery
This commit is contained in:
parent
15bad8bbfd
commit
defa61f3fb
7 changed files with 20 additions and 55 deletions
|
@ -2695,28 +2695,12 @@ impl<'a> Parser<'a> {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut recovery_field = None;
|
let mut parsed_field = None;
|
||||||
if let token::Ident(ident, _) = self.token {
|
|
||||||
if !self.token.is_reserved_ident() {
|
|
||||||
let mut ident = ident.clone();
|
|
||||||
ident.span = self.span;
|
|
||||||
recovery_field = Some(ast::Field {
|
|
||||||
ident,
|
|
||||||
span: self.span,
|
|
||||||
expr: self.mk_expr(self.span, ExprKind::Err, ThinVec::new()),
|
|
||||||
is_shorthand: true,
|
|
||||||
attrs: ThinVec::new(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match self.parse_field() {
|
match self.parse_field() {
|
||||||
Ok(f) => fields.push(f),
|
Ok(f) => parsed_field = Some(f),
|
||||||
Err(mut e) => {
|
Err(mut e) => {
|
||||||
e.span_label(struct_sp, "while parsing this struct");
|
e.span_label(struct_sp, "while parsing this struct");
|
||||||
e.emit();
|
e.emit();
|
||||||
if let Some(f) = recovery_field {
|
|
||||||
fields.push(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the next token is a comma, then try to parse
|
// If the next token is a comma, then try to parse
|
||||||
// what comes next as additional fields, rather than
|
// what comes next as additional fields, rather than
|
||||||
|
@ -2732,7 +2716,10 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
match self.expect_one_of(&[token::Comma],
|
match self.expect_one_of(&[token::Comma],
|
||||||
&[token::CloseDelim(token::Brace)]) {
|
&[token::CloseDelim(token::Brace)]) {
|
||||||
Ok(()) => {}
|
Ok(()) => if let Some(f) = parsed_field {
|
||||||
|
// only include the field if there's no parse error
|
||||||
|
fields.push(f);
|
||||||
|
}
|
||||||
Err(mut e) => {
|
Err(mut e) => {
|
||||||
e.span_label(struct_sp, "while parsing this struct");
|
e.span_label(struct_sp, "while parsing this struct");
|
||||||
e.emit();
|
e.emit();
|
||||||
|
|
|
@ -7,7 +7,6 @@ fn main() {
|
||||||
let bar = 1.5f32;
|
let bar = 1.5f32;
|
||||||
let _ = Foo { bar.into(), bat: -1, . };
|
let _ = Foo { bar.into(), bat: -1, . };
|
||||||
//~^ ERROR expected one of
|
//~^ ERROR expected one of
|
||||||
//~| ERROR mismatched types
|
//~| ERROR missing fields `bar`, `baz` in initializer of `Foo`
|
||||||
//~| ERROR missing field `baz` in initializer of `Foo`
|
|
||||||
//~| ERROR expected identifier, found `.`
|
//~| ERROR expected identifier, found `.`
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,23 +26,12 @@ error[E0063]: missing field `bat` in initializer of `Foo`
|
||||||
LL | let _ = Foo { bar: .5, baz: 42 };
|
LL | let _ = Foo { bar: .5, baz: 42 };
|
||||||
| ^^^ missing `bat`
|
| ^^^ missing `bat`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0063]: missing fields `bar`, `baz` in initializer of `Foo`
|
||||||
--> $DIR/issue-52496.rs:8:19
|
|
||||||
|
|
|
||||||
LL | let _ = Foo { bar.into(), bat: -1, . };
|
|
||||||
| ^^^ expected f64, found f32
|
|
||||||
help: you can cast an `f32` to `f64` in a lossless way
|
|
||||||
|
|
|
||||||
LL | let _ = Foo { bar.into().into(), bat: -1, . };
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
||||||
error[E0063]: missing field `baz` in initializer of `Foo`
|
|
||||||
--> $DIR/issue-52496.rs:8:13
|
--> $DIR/issue-52496.rs:8:13
|
||||||
|
|
|
|
||||||
LL | let _ = Foo { bar.into(), bat: -1, . };
|
LL | let _ = Foo { bar.into(), bat: -1, . };
|
||||||
| ^^^ missing `baz`
|
| ^^^ missing `bar`, `baz`
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
Some errors occurred: E0063, E0308.
|
For more information about this error, try `rustc --explain E0063`.
|
||||||
For more information about an error, try `rustc --explain E0063`.
|
|
||||||
|
|
|
@ -7,5 +7,5 @@ fn main() {
|
||||||
let a = S { foo: (), bar: () };
|
let a = S { foo: (), bar: () };
|
||||||
let b = S { foo: () with a };
|
let b = S { foo: () with a };
|
||||||
//~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `with`
|
//~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `with`
|
||||||
//~| ERROR missing field `bar` in initializer of `main::S`
|
//~| ERROR missing fields `bar`, `foo` in initializer of `main::S`
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,11 @@ LL | let b = S { foo: () with a };
|
||||||
| |
|
| |
|
||||||
| while parsing this struct
|
| while parsing this struct
|
||||||
|
|
||||||
error[E0063]: missing field `bar` in initializer of `main::S`
|
error[E0063]: missing fields `bar`, `foo` in initializer of `main::S`
|
||||||
--> $DIR/removed-syntax-with-1.rs:8:13
|
--> $DIR/removed-syntax-with-1.rs:8:13
|
||||||
|
|
|
|
||||||
LL | let b = S { foo: () with a };
|
LL | let b = S { foo: () with a };
|
||||||
| ^ missing `bar`
|
| ^ missing `bar`, `foo`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,5 @@ fn main() {
|
||||||
let a = S { foo: (), bar: () };
|
let a = S { foo: (), bar: () };
|
||||||
let b = S { foo: (), with a };
|
let b = S { foo: (), with a };
|
||||||
//~^ ERROR expected one of `,` or `}`, found `a`
|
//~^ ERROR expected one of `,` or `}`, found `a`
|
||||||
//~| ERROR cannot find value `with` in this scope
|
//~| ERROR missing field `bar` in initializer of `main::S`
|
||||||
//~| ERROR struct `main::S` has no field named `with`
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,21 +6,12 @@ LL | let b = S { foo: (), with a };
|
||||||
| |
|
| |
|
||||||
| while parsing this struct
|
| while parsing this struct
|
||||||
|
|
||||||
error[E0425]: cannot find value `with` in this scope
|
error[E0063]: missing field `bar` in initializer of `main::S`
|
||||||
--> $DIR/removed-syntax-with-2.rs:8:26
|
--> $DIR/removed-syntax-with-2.rs:8:13
|
||||||
|
|
|
|
||||||
LL | let b = S { foo: (), with a };
|
LL | let b = S { foo: (), with a };
|
||||||
| ^^^^ not found in this scope
|
| ^ missing `bar`
|
||||||
|
|
||||||
error[E0560]: struct `main::S` has no field named `with`
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/removed-syntax-with-2.rs:8:26
|
|
||||||
|
|
|
||||||
LL | let b = S { foo: (), with a };
|
|
||||||
| ^^^^ `main::S` does not have this field
|
|
||||||
|
|
|
||||||
= note: available fields are: `foo`, `bar`
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
For more information about this error, try `rustc --explain E0063`.
|
||||||
|
|
||||||
Some errors occurred: E0425, E0560.
|
|
||||||
For more information about an error, try `rustc --explain E0425`.
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue