11use super :: diagnostics:: { dummy_arg, ConsumeClosingDelim } ;
2- use super :: ty:: { AllowPlus , RecoverQPath , RecoverReturnSign } ;
2+ use super :: ty:: { AllowPlus , RecoverAnonymousStructOrUnion , RecoverQPath , RecoverReturnSign } ;
33use super :: { AttrWrapper , FollowedByType , ForceCollect , Parser , PathStyle , TrailingToken } ;
44use crate :: errors:: { self , MacroExpandsToAdtField } ;
55use crate :: fluent_generated as fluent;
@@ -602,7 +602,7 @@ impl<'a> Parser<'a> {
602602 Some ( self . mk_ty ( self . prev_token . span , TyKind :: Err ) )
603603 } else if has_for || self . token . can_begin_type ( ) {
604604 snapshot_before_last_ty = self . create_snapshot_for_diagnostic ( ) ;
605- Some ( self . parse_ty_no_anon_recovery ( ) ?)
605+ Some ( self . parse_ty ( ) ?)
606606 } else {
607607 None
608608 } ;
@@ -615,7 +615,7 @@ impl<'a> Parser<'a> {
615615 if let Some ( mut err) = err {
616616 let mut snapshot = snapshot_before_last_ty;
617617
618- if snapshot. can_start_anonymous_type ( ) {
618+ if snapshot. can_start_anonymous_union ( ) {
619619 let recover_result = {
620620 let recover_last_ty = match snapshot. parse_ty ( ) {
621621 Ok ( ty) => Some ( ty) ,
@@ -1665,11 +1665,26 @@ impl<'a> Parser<'a> {
16651665 Ok ( ( class_name, ItemKind :: Union ( vdata, generics) ) )
16661666 }
16671667
1668- pub ( crate ) fn parse_record_struct_body (
1668+ fn parse_record_struct_body (
16691669 & mut self ,
16701670 adt_ty : & str ,
16711671 ident_span : Span ,
16721672 parsed_where : bool ,
1673+ ) -> PResult < ' a , ( ThinVec < FieldDef > , /* recovered */ bool ) > {
1674+ self . parse_record_struct_body_common (
1675+ adt_ty,
1676+ ident_span,
1677+ parsed_where,
1678+ RecoverAnonymousStructOrUnion :: No ,
1679+ )
1680+ }
1681+
1682+ pub ( crate ) fn parse_record_struct_body_common (
1683+ & mut self ,
1684+ adt_ty : & str ,
1685+ ident_span : Span ,
1686+ parsed_where : bool ,
1687+ recover_anonymous_struct_or_union : RecoverAnonymousStructOrUnion ,
16731688 ) -> PResult < ' a , ( ThinVec < FieldDef > , /* recovered */ bool ) > {
16741689 let mut fields = ThinVec :: new ( ) ;
16751690 let mut recovered = false ;
@@ -1683,6 +1698,16 @@ impl<'a> Parser<'a> {
16831698 match field {
16841699 Ok ( field) => fields. push ( field) ,
16851700 Err ( mut err) => {
1701+ // When recovering the anonymous structs or unions, we should't emit the error
1702+ // immediately, because it may also be a type path `union` followed by a block,
1703+ // such as `impl union { fn foo() {} }`. Here we are actaully not parsing a
1704+ // record struct body but an `impl` body.
1705+ //
1706+ // Instead, the error should be thrown and handled by the caller
1707+ // `parse_anonymous_struct_or_union`.
1708+ if recover_anonymous_struct_or_union == RecoverAnonymousStructOrUnion :: Yes {
1709+ return Err ( err) ;
1710+ }
16861711 err. span_label ( ident_span, format ! ( "while parsing this {adt_ty}" ) ) ;
16871712 err. emit ( ) ;
16881713 break ;
@@ -1965,85 +1990,83 @@ impl<'a> Parser<'a> {
19651990 /// for better diagnostics and suggestions.
19661991 fn parse_field_ident ( & mut self , adt_ty : & str , lo : Span ) -> PResult < ' a , Ident > {
19671992 let ( ident, is_raw) = self . ident_or_err ( true ) ?;
1968- if !is_raw && ident. is_reserved ( ) {
1993+ if ident. name == kw:: Underscore {
1994+ self . sess . gated_spans . gate ( sym:: unnamed_fields, lo) ;
1995+ } else if !is_raw && ident. is_reserved ( ) {
19691996 let snapshot = self . create_snapshot_for_diagnostic ( ) ;
1970- if ident. name == kw:: Underscore {
1971- self . sess . gated_spans . gate ( sym:: unnamed_fields, lo) ;
1972- } else {
1973- let err = if self . check_fn_front_matter ( false , Case :: Sensitive ) {
1974- let inherited_vis = Visibility {
1975- span : rustc_span:: DUMMY_SP ,
1976- kind : VisibilityKind :: Inherited ,
1977- tokens : None ,
1978- } ;
1979- // We use `parse_fn` to get a span for the function
1980- let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : true } ;
1981- match self . parse_fn (
1982- & mut AttrVec :: new ( ) ,
1983- fn_parse_mode,
1984- lo,
1985- & inherited_vis,
1986- Case :: Insensitive ,
1987- ) {
1988- Ok ( _) => {
1989- let mut err = self . struct_span_err (
1990- lo. to ( self . prev_token . span ) ,
1991- format ! ( "functions are not allowed in {adt_ty} definitions" ) ,
1992- ) ;
1993- err. help (
1994- "unlike in C++, Java, and C#, functions are declared in `impl` blocks" ,
1995- ) ;
1996- err. help ( "see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information" ) ;
1997- err
1998- }
1999- Err ( err) => {
2000- err. cancel ( ) ;
2001- self . restore_snapshot ( snapshot) ;
2002- self . expected_ident_found_err ( )
2003- }
1997+ let err = if self . check_fn_front_matter ( false , Case :: Sensitive ) {
1998+ let inherited_vis = Visibility {
1999+ span : rustc_span:: DUMMY_SP ,
2000+ kind : VisibilityKind :: Inherited ,
2001+ tokens : None ,
2002+ } ;
2003+ // We use `parse_fn` to get a span for the function
2004+ let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : true } ;
2005+ match self . parse_fn (
2006+ & mut AttrVec :: new ( ) ,
2007+ fn_parse_mode,
2008+ lo,
2009+ & inherited_vis,
2010+ Case :: Insensitive ,
2011+ ) {
2012+ Ok ( _) => {
2013+ let mut err = self . struct_span_err (
2014+ lo. to ( self . prev_token . span ) ,
2015+ format ! ( "functions are not allowed in {adt_ty} definitions" ) ,
2016+ ) ;
2017+ err. help (
2018+ "unlike in C++, Java, and C#, functions are declared in `impl` blocks" ,
2019+ ) ;
2020+ err. help ( "see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information" ) ;
2021+ err
20042022 }
2005- } else if self . eat_keyword ( kw:: Struct ) {
2006- match self . parse_item_struct ( ) {
2007- Ok ( ( ident, _) ) => {
2008- let mut err = self . struct_span_err (
2009- lo. with_hi ( ident. span . hi ( ) ) ,
2010- format ! ( "structs are not allowed in {adt_ty} definitions" ) ,
2011- ) ;
2012- err. help ( "consider creating a new `struct` definition instead of nesting" ) ;
2013- err
2014- }
2015- Err ( err) => {
2016- err. cancel ( ) ;
2017- self . restore_snapshot ( snapshot) ;
2018- self . expected_ident_found_err ( )
2019- }
2023+ Err ( err) => {
2024+ err. cancel ( ) ;
2025+ self . restore_snapshot ( snapshot) ;
2026+ self . expected_ident_found_err ( )
20202027 }
2021- } else {
2022- let mut err = self . expected_ident_found_err ( ) ;
2023- if self . eat_keyword_noexpect ( kw:: Let )
2024- && let removal_span = self . prev_token . span . until ( self . token . span )
2025- && let Ok ( ident) = self . parse_ident_common ( false )
2026- // Cancel this error, we don't need it.
2027- . map_err ( |err| err. cancel ( ) )
2028- && self . token . kind == TokenKind :: Colon
2029- {
2030- err. span_suggestion (
2031- removal_span,
2032- "remove this `let` keyword" ,
2033- String :: new ( ) ,
2034- Applicability :: MachineApplicable ,
2028+ }
2029+ } else if self . eat_keyword ( kw:: Struct ) {
2030+ match self . parse_item_struct ( ) {
2031+ Ok ( ( ident, _) ) => {
2032+ let mut err = self . struct_span_err (
2033+ lo. with_hi ( ident. span . hi ( ) ) ,
2034+ format ! ( "structs are not allowed in {adt_ty} definitions" ) ,
20352035 ) ;
2036- err. note ( "the `let` keyword is not allowed in `struct` fields ") ;
2037- err. note ( "see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information" ) ;
2038- err . emit ( ) ;
2039- return Ok ( ident ) ;
2040- } else {
2036+ err. help ( "consider creating a new `struct` definition instead of nesting ") ;
2037+ err
2038+ }
2039+ Err ( err ) => {
2040+ err . cancel ( ) ;
20412041 self . restore_snapshot ( snapshot) ;
2042+ self . expected_ident_found_err ( )
20422043 }
2043- err
2044- } ;
2045- return Err ( err) ;
2046- }
2044+ }
2045+ } else {
2046+ let mut err = self . expected_ident_found_err ( ) ;
2047+ if self . eat_keyword_noexpect ( kw:: Let )
2048+ && let removal_span = self . prev_token . span . until ( self . token . span )
2049+ && let Ok ( ident) = self . parse_ident_common ( false )
2050+ // Cancel this error, we don't need it.
2051+ . map_err ( |err| err. cancel ( ) )
2052+ && self . token . kind == TokenKind :: Colon
2053+ {
2054+ err. span_suggestion (
2055+ removal_span,
2056+ "remove this `let` keyword" ,
2057+ String :: new ( ) ,
2058+ Applicability :: MachineApplicable ,
2059+ ) ;
2060+ err. note ( "the `let` keyword is not allowed in `struct` fields" ) ;
2061+ err. note ( "see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information" ) ;
2062+ err. emit ( ) ;
2063+ return Ok ( ident) ;
2064+ } else {
2065+ self . restore_snapshot ( snapshot) ;
2066+ }
2067+ err
2068+ } ;
2069+ return Err ( err) ;
20472070 }
20482071 self . bump ( ) ;
20492072 Ok ( ident)
0 commit comments