diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-03-22 19:31:24 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-03-22 19:31:24 +0100 |
| commit | 5a0e4510a805aa7feb93f7a34000be7d5d9a6249 (patch) | |
| tree | df4aff066dccc48f8c83eb25920296a15a8c491e /src/libsyntax/parse | |
| parent | adbfcea58f89dee842519d4ef0cbaefe09fac3a5 (diff) | |
| parent | 757eb679927e2c85457f567487e887eb080eb7cb (diff) | |
| download | rust-5a0e4510a805aa7feb93f7a34000be7d5d9a6249.tar.gz rust-5a0e4510a805aa7feb93f7a34000be7d5d9a6249.zip | |
Rollup merge of #59266 - estebank:struct-parse-recovery, r=petrochenkov
Do not complain about non-existing fields after parse recovery When failing to parse struct-like enum variants, the ADT gets recorded as having no fields. Record that we have actually recovered during parsing of this variant to avoid complaing about non-existing fields when actually using it. Fix #57361.
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7a4a687f90e..648ee771ddb 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6837,14 +6837,16 @@ impl<'a> Parser<'a> { VariantData::Unit(ast::DUMMY_NODE_ID) } else { // If we see: `struct Foo<T> where T: Copy { ... }` - VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID) + let (fields, recovered) = self.parse_record_struct_body()?; + VariantData::Struct(fields, ast::DUMMY_NODE_ID, recovered) } // No `where` so: `struct Foo<T>;` } else if self.eat(&token::Semi) { VariantData::Unit(ast::DUMMY_NODE_ID) // Record-style struct definition } else if self.token == token::OpenDelim(token::Brace) { - VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID) + let (fields, recovered) = self.parse_record_struct_body()?; + VariantData::Struct(fields, ast::DUMMY_NODE_ID, recovered) // Tuple-style struct definition with optional where-clause. } else if self.token == token::OpenDelim(token::Paren) { let body = VariantData::Tuple(self.parse_tuple_struct_body()?, ast::DUMMY_NODE_ID); @@ -6872,9 +6874,11 @@ impl<'a> Parser<'a> { let vdata = if self.token.is_keyword(keywords::Where) { generics.where_clause = self.parse_where_clause()?; - VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID) + let (fields, recovered) = self.parse_record_struct_body()?; + VariantData::Struct(fields, ast::DUMMY_NODE_ID, recovered) } else if self.token == token::OpenDelim(token::Brace) { - VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID) + let (fields, recovered) = self.parse_record_struct_body()?; + VariantData::Struct(fields, ast::DUMMY_NODE_ID, recovered) } else { let token_str = self.this_token_descr(); let mut err = self.fatal(&format!( @@ -6906,12 +6910,16 @@ impl<'a> Parser<'a> { } } - fn parse_record_struct_body(&mut self) -> PResult<'a, Vec<StructField>> { + fn parse_record_struct_body( + &mut self, + ) -> PResult<'a, (Vec<StructField>, /* recovered */ bool)> { let mut fields = Vec::new(); + let mut recovered = false; if self.eat(&token::OpenDelim(token::Brace)) { while self.token != token::CloseDelim(token::Brace) { let field = self.parse_struct_decl_field().map_err(|e| { self.recover_stmt(); + recovered = true; e }); match field { @@ -6930,7 +6938,7 @@ impl<'a> Parser<'a> { return Err(err); } - Ok(fields) + Ok((fields, recovered)) } fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec<StructField>> { @@ -7693,12 +7701,14 @@ impl<'a> Parser<'a> { if self.check(&token::OpenDelim(token::Brace)) { // Parse a struct variant. all_nullary = false; - struct_def = VariantData::Struct(self.parse_record_struct_body()?, - ast::DUMMY_NODE_ID); + let (fields, recovered) = self.parse_record_struct_body()?; + struct_def = VariantData::Struct(fields, ast::DUMMY_NODE_ID, recovered); } else if self.check(&token::OpenDelim(token::Paren)) { all_nullary = false; - struct_def = VariantData::Tuple(self.parse_tuple_struct_body()?, - ast::DUMMY_NODE_ID); + struct_def = VariantData::Tuple( + self.parse_tuple_struct_body()?, + ast::DUMMY_NODE_ID, + ); } else if self.eat(&token::Eq) { disr_expr = Some(AnonConst { id: ast::DUMMY_NODE_ID, |
