mirror of
https://github.com/rust-lang/rust.git
synced 2025-10-03 10:47:16 +00:00
Rollup merge of #142798 - camsteffen:recover-semi, r=compiler-errors
Don't fail to parse a struct if a semicolon is used to separate fields The first commit is a small refactor.
This commit is contained in:
commit
194e58c75c
@ -1781,7 +1781,7 @@ impl<'a> Parser<'a> {
|
||||
let mut recovered = Recovered::No;
|
||||
if self.eat(exp!(OpenBrace)) {
|
||||
while self.token != token::CloseBrace {
|
||||
match self.parse_field_def(adt_ty) {
|
||||
match self.parse_field_def(adt_ty, ident_span) {
|
||||
Ok(field) => {
|
||||
fields.push(field);
|
||||
}
|
||||
@ -1894,7 +1894,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
/// Parses an element of a struct declaration.
|
||||
fn parse_field_def(&mut self, adt_ty: &str) -> PResult<'a, FieldDef> {
|
||||
fn parse_field_def(&mut self, adt_ty: &str, ident_span: Span) -> PResult<'a, FieldDef> {
|
||||
self.recover_vcs_conflict_marker();
|
||||
let attrs = self.parse_outer_attributes()?;
|
||||
self.recover_vcs_conflict_marker();
|
||||
@ -1902,7 +1902,7 @@ impl<'a> Parser<'a> {
|
||||
let lo = this.token.span;
|
||||
let vis = this.parse_visibility(FollowedByType::No)?;
|
||||
let safety = this.parse_unsafe_field();
|
||||
this.parse_single_struct_field(adt_ty, lo, vis, safety, attrs)
|
||||
this.parse_single_struct_field(adt_ty, lo, vis, safety, attrs, ident_span)
|
||||
.map(|field| (field, Trailing::No, UsePreAttrPos::No))
|
||||
})
|
||||
}
|
||||
@ -1915,28 +1915,27 @@ impl<'a> Parser<'a> {
|
||||
vis: Visibility,
|
||||
safety: Safety,
|
||||
attrs: AttrVec,
|
||||
ident_span: Span,
|
||||
) -> PResult<'a, FieldDef> {
|
||||
let mut seen_comma: bool = false;
|
||||
let a_var = self.parse_name_and_ty(adt_ty, lo, vis, safety, attrs)?;
|
||||
if self.token == token::Comma {
|
||||
seen_comma = true;
|
||||
}
|
||||
if self.eat(exp!(Semi)) {
|
||||
let sp = self.prev_token.span;
|
||||
let mut err =
|
||||
self.dcx().struct_span_err(sp, format!("{adt_ty} fields are separated by `,`"));
|
||||
err.span_suggestion_short(
|
||||
sp,
|
||||
"replace `;` with `,`",
|
||||
",",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
return Err(err);
|
||||
}
|
||||
match self.token.kind {
|
||||
token::Comma => {
|
||||
self.bump();
|
||||
}
|
||||
token::Semi => {
|
||||
self.bump();
|
||||
let sp = self.prev_token.span;
|
||||
let mut err =
|
||||
self.dcx().struct_span_err(sp, format!("{adt_ty} fields are separated by `,`"));
|
||||
err.span_suggestion_short(
|
||||
sp,
|
||||
"replace `;` with `,`",
|
||||
",",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.span_label(ident_span, format!("while parsing this {adt_ty}"));
|
||||
err.emit();
|
||||
}
|
||||
token::CloseBrace => {}
|
||||
token::DocComment(..) => {
|
||||
let previous_span = self.prev_token.span;
|
||||
@ -1945,19 +1944,11 @@ impl<'a> Parser<'a> {
|
||||
missing_comma: None,
|
||||
};
|
||||
self.bump(); // consume the doc comment
|
||||
let comma_after_doc_seen = self.eat(exp!(Comma));
|
||||
// `seen_comma` is always false, because we are inside doc block
|
||||
// condition is here to make code more readable
|
||||
if !seen_comma && comma_after_doc_seen {
|
||||
seen_comma = true;
|
||||
}
|
||||
if comma_after_doc_seen || self.token == token::CloseBrace {
|
||||
if self.eat(exp!(Comma)) || self.token == token::CloseBrace {
|
||||
self.dcx().emit_err(err);
|
||||
} else {
|
||||
if !seen_comma {
|
||||
let sp = previous_span.shrink_to_hi();
|
||||
err.missing_comma = Some(sp);
|
||||
}
|
||||
let sp = previous_span.shrink_to_hi();
|
||||
err.missing_comma = Some(sp);
|
||||
return Err(self.dcx().create_err(err));
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ struct Foo {
|
||||
//~^ ERROR struct fields are separated by `,`
|
||||
}
|
||||
|
||||
union Bar { //~ ERROR
|
||||
union Bar {
|
||||
foo: i32;
|
||||
//~^ ERROR union fields are separated by `,`
|
||||
}
|
||||
@ -13,4 +13,6 @@ enum Baz {
|
||||
//~^ ERROR struct fields are separated by `,`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
fn main() {
|
||||
let _ = Foo { foo: "" }; //~ ERROR mismatched types
|
||||
}
|
||||
|
@ -22,14 +22,12 @@ LL | Qux { foo: i32; }
|
||||
| |
|
||||
| while parsing this struct
|
||||
|
||||
error: unions cannot have zero fields
|
||||
--> $DIR/recover-field-semi.rs:6:1
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recover-field-semi.rs:17:24
|
||||
|
|
||||
LL | / union Bar {
|
||||
LL | | foo: i32;
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_^
|
||||
LL | let _ = Foo { foo: "" };
|
||||
| ^^ expected `i32`, found `&str`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
Loading…
x
Reference in New Issue
Block a user