1
1
use super :: diagnostics:: { dummy_arg, ConsumeClosingDelim } ;
2
- use super :: ty:: { AllowPlus , RecoverQPath , RecoverReturnSign } ;
2
+ use super :: ty:: { AllowPlus , RecoverAnonymousStructOrUnion , RecoverQPath , RecoverReturnSign } ;
3
3
use super :: { AttrWrapper , FollowedByType , ForceCollect , Parser , PathStyle , TrailingToken } ;
4
4
use crate :: errors:: { self , MacroExpandsToAdtField } ;
5
5
use crate :: fluent_generated as fluent;
@@ -602,7 +602,7 @@ impl<'a> Parser<'a> {
602
602
Some ( self . mk_ty ( self . prev_token . span , TyKind :: Err ) )
603
603
} else if has_for || self . token . can_begin_type ( ) {
604
604
snapshot_before_last_ty = self . create_snapshot_for_diagnostic ( ) ;
605
- Some ( self . parse_ty_no_anon_recovery ( ) ?)
605
+ Some ( self . parse_ty ( ) ?)
606
606
} else {
607
607
None
608
608
} ;
@@ -615,7 +615,7 @@ impl<'a> Parser<'a> {
615
615
if let Some ( mut err) = err {
616
616
let mut snapshot = snapshot_before_last_ty;
617
617
618
- if snapshot. can_start_anonymous_type ( ) {
618
+ if snapshot. can_start_anonymous_union ( ) {
619
619
let recover_result = {
620
620
let recover_last_ty = match snapshot. parse_ty ( ) {
621
621
Ok ( ty) => Some ( ty) ,
@@ -1665,11 +1665,26 @@ impl<'a> Parser<'a> {
1665
1665
Ok ( ( class_name, ItemKind :: Union ( vdata, generics) ) )
1666
1666
}
1667
1667
1668
- pub ( crate ) fn parse_record_struct_body (
1668
+ fn parse_record_struct_body (
1669
1669
& mut self ,
1670
1670
adt_ty : & str ,
1671
1671
ident_span : Span ,
1672
1672
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 ,
1673
1688
) -> PResult < ' a , ( ThinVec < FieldDef > , /* recovered */ bool ) > {
1674
1689
let mut fields = ThinVec :: new ( ) ;
1675
1690
let mut recovered = false ;
@@ -1683,6 +1698,16 @@ impl<'a> Parser<'a> {
1683
1698
match field {
1684
1699
Ok ( field) => fields. push ( field) ,
1685
1700
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
+ }
1686
1711
err. span_label ( ident_span, format ! ( "while parsing this {adt_ty}" ) ) ;
1687
1712
err. emit ( ) ;
1688
1713
break ;
@@ -1965,85 +1990,83 @@ impl<'a> Parser<'a> {
1965
1990
/// for better diagnostics and suggestions.
1966
1991
fn parse_field_ident ( & mut self , adt_ty : & str , lo : Span ) -> PResult < ' a , Ident > {
1967
1992
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 ( ) {
1969
1996
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
2004
2022
}
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 ( )
2020
2027
}
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" ) ,
2035
2035
) ;
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 ( ) ;
2041
2041
self . restore_snapshot ( snapshot) ;
2042
+ self . expected_ident_found_err ( )
2042
2043
}
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) ;
2047
2070
}
2048
2071
self . bump ( ) ;
2049
2072
Ok ( ident)
0 commit comments