@@ -9,14 +9,15 @@ use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness
99use syntax:: ast:: { Visibility , VisibilityKind , Mutability , FnHeader , ForeignItem , ForeignItemKind } ;
1010use syntax:: ast:: { Ty , TyKind , Generics , TraitRef , EnumDef , VariantData , StructField } ;
1111use syntax:: ast:: { Mac , MacDelimiter , Block , BindingMode , FnDecl , FnSig , SelfKind , Param } ;
12+ use syntax:: print:: pprust;
1213use syntax:: ptr:: P ;
1314use syntax:: ThinVec ;
1415use syntax:: token;
1516use syntax:: tokenstream:: { TokenTree , TokenStream } ;
1617use syntax:: source_map:: { self , respan, Span } ;
1718use syntax:: struct_span_err;
1819use syntax_pos:: BytePos ;
19- use syntax_pos:: symbol:: { kw, sym} ;
20+ use syntax_pos:: symbol:: { kw, sym, Symbol } ;
2021
2122use rustc_error_codes:: * ;
2223
@@ -1341,6 +1342,10 @@ impl<'a> Parser<'a> {
13411342 let vlo = self . token . span ;
13421343
13431344 let vis = self . parse_visibility ( FollowedByType :: No ) ?;
1345+ if !self . recover_nested_adt_item ( kw:: Enum ) ? {
1346+ // Item already parsed, we need to skip this variant.
1347+ continue
1348+ }
13441349 let ident = self . parse_ident ( ) ?;
13451350
13461351 let struct_def = if self . check ( & token:: OpenDelim ( token:: Brace ) ) {
@@ -1742,6 +1747,36 @@ impl<'a> Parser<'a> {
17421747 ) . emit ( ) ;
17431748 }
17441749
1750+ /// Checks if current token is one of tokens which cannot be nested like `kw::Enum`. In case
1751+ /// it is, we try to parse the item and report error about nested types.
1752+ fn recover_nested_adt_item ( & mut self , keyword : Symbol ) -> PResult < ' a , bool > {
1753+ if self . token . is_keyword ( kw:: Enum ) ||
1754+ self . token . is_keyword ( kw:: Struct ) ||
1755+ self . token . is_keyword ( kw:: Union ) {
1756+
1757+ let prev_token = self . token . clone ( ) ;
1758+ let item = self . parse_item ( ) ?;
1759+ if self . token == token:: Comma {
1760+ self . bump ( ) ;
1761+ }
1762+
1763+ let mut err = self . struct_span_err (
1764+ prev_token. span ,
1765+ & format ! ( "`{}` definition cannot be nested inside `{}`" , pprust:: token_to_string( & prev_token) , keyword) ,
1766+ ) ;
1767+ err. span_suggestion (
1768+ item. unwrap ( ) . span ,
1769+ & format ! ( "consider creating a new `{}` definition instead of nesting" , pprust:: token_to_string( & prev_token) ) ,
1770+ String :: new ( ) ,
1771+ Applicability :: MaybeIncorrect ,
1772+ ) ;
1773+ err. emit ( ) ;
1774+ // We successfully parsed the item but we must inform the caller about nested problem.
1775+ return Ok ( false )
1776+ }
1777+ Ok ( true )
1778+ }
1779+
17451780 fn mk_item ( & self , span : Span , ident : Ident , kind : ItemKind , vis : Visibility ,
17461781 attrs : Vec < Attribute > ) -> P < Item > {
17471782 P ( Item {
0 commit comments