@@ -11,6 +11,7 @@ use rustc_ast::{
1111    self  as  ast,  BareFnTy ,  FnRetTy ,  GenericBound ,  GenericBounds ,  GenericParam ,  Generics ,  Lifetime , 
1212    MacCall ,  MutTy ,  Mutability ,  PolyTraitRef ,  TraitBoundModifier ,  TraitObjectSyntax ,  Ty ,  TyKind , 
1313} ; 
14+ use  rustc_ast_pretty:: pprust; 
1415use  rustc_errors:: { pluralize,  struct_span_err,  Applicability ,  PResult } ; 
1516use  rustc_span:: source_map:: Span ; 
1617use  rustc_span:: symbol:: { kw,  sym,  Ident } ; 
@@ -43,17 +44,24 @@ pub(super) enum AllowPlus {
4344    No , 
4445} 
4546
46- #[ derive( PartialEq ) ]  
47+ #[ derive( PartialEq ,   Clone ,   Copy ) ]  
4748pub ( super )  enum  RecoverQPath  { 
4849    Yes , 
4950    No , 
5051} 
5152
53+ #[ derive( PartialEq ,  Clone ,  Copy ) ]  
5254pub ( super )  enum  RecoverQuestionMark  { 
5355    Yes , 
5456    No , 
5557} 
5658
59+ #[ derive( PartialEq ,  Clone ,  Copy ) ]  
60+ pub ( super )  enum  RecoverAnonEnum  { 
61+     Yes , 
62+     No , 
63+ } 
64+ 
5765/// Signals whether parsing a type should recover `->`. 
5866/// 
5967/// More specifically, when parsing a function like: 
@@ -86,7 +94,7 @@ impl RecoverReturnSign {
8694} 
8795
8896// Is `...` (`CVarArgs`) legal at this level of type parsing? 
89- #[ derive( PartialEq ) ]  
97+ #[ derive( PartialEq ,   Clone ,   Copy ) ]  
9098enum  AllowCVariadic  { 
9199    Yes , 
92100    No , 
@@ -111,6 +119,7 @@ impl<'a> Parser<'a> {
111119            RecoverReturnSign :: Yes , 
112120            None , 
113121            RecoverQuestionMark :: Yes , 
122+             RecoverAnonEnum :: No , 
114123        ) 
115124    } 
116125
@@ -125,6 +134,7 @@ impl<'a> Parser<'a> {
125134            RecoverReturnSign :: Yes , 
126135            Some ( ty_params) , 
127136            RecoverQuestionMark :: Yes , 
137+             RecoverAnonEnum :: No , 
128138        ) 
129139    } 
130140
@@ -139,6 +149,7 @@ impl<'a> Parser<'a> {
139149            RecoverReturnSign :: Yes , 
140150            None , 
141151            RecoverQuestionMark :: Yes , 
152+             RecoverAnonEnum :: Yes , 
142153        ) 
143154    } 
144155
@@ -156,6 +167,7 @@ impl<'a> Parser<'a> {
156167            RecoverReturnSign :: Yes , 
157168            None , 
158169            RecoverQuestionMark :: Yes , 
170+             RecoverAnonEnum :: No , 
159171        ) 
160172    } 
161173
@@ -169,6 +181,7 @@ impl<'a> Parser<'a> {
169181            RecoverReturnSign :: Yes , 
170182            None , 
171183            RecoverQuestionMark :: No , 
184+             RecoverAnonEnum :: No , 
172185        ) 
173186    } 
174187
@@ -180,6 +193,7 @@ impl<'a> Parser<'a> {
180193            RecoverReturnSign :: Yes , 
181194            None , 
182195            RecoverQuestionMark :: No , 
196+             RecoverAnonEnum :: No , 
183197        ) 
184198    } 
185199
@@ -192,6 +206,7 @@ impl<'a> Parser<'a> {
192206            RecoverReturnSign :: OnlyFatArrow , 
193207            None , 
194208            RecoverQuestionMark :: Yes , 
209+             RecoverAnonEnum :: No , 
195210        ) 
196211    } 
197212
@@ -211,6 +226,7 @@ impl<'a> Parser<'a> {
211226                recover_return_sign, 
212227                None , 
213228                RecoverQuestionMark :: Yes , 
229+                 RecoverAnonEnum :: Yes , 
214230            ) ?; 
215231            FnRetTy :: Ty ( ty) 
216232        }  else  if  recover_return_sign. can_recover ( & self . token . kind )  { 
@@ -232,6 +248,7 @@ impl<'a> Parser<'a> {
232248                recover_return_sign, 
233249                None , 
234250                RecoverQuestionMark :: Yes , 
251+                 RecoverAnonEnum :: Yes , 
235252            ) ?; 
236253            FnRetTy :: Ty ( ty) 
237254        }  else  { 
@@ -247,6 +264,7 @@ impl<'a> Parser<'a> {
247264        recover_return_sign :  RecoverReturnSign , 
248265        ty_generics :  Option < & Generics > , 
249266        recover_question_mark :  RecoverQuestionMark , 
267+         recover_anon_enum :  RecoverAnonEnum , 
250268    )  -> PResult < ' a ,  P < Ty > >  { 
251269        let  allow_qpath_recovery = recover_qpath == RecoverQPath :: Yes ; 
252270        maybe_recover_from_interpolated_ty_qpath ! ( self ,  allow_qpath_recovery) ; 
@@ -325,14 +343,55 @@ impl<'a> Parser<'a> {
325343        let  mut  ty = self . mk_ty ( span,  kind) ; 
326344
327345        // Try to recover from use of `+` with incorrect priority. 
328-         if  matches ! ( allow_plus,   AllowPlus :: Yes )  { 
346+         if  allow_plus ==  AllowPlus :: Yes  { 
329347            self . maybe_recover_from_bad_type_plus ( & ty) ?; 
330348        }  else  { 
331349            self . maybe_report_ambiguous_plus ( impl_dyn_multi,  & ty) ; 
332350        } 
333-         if  let   RecoverQuestionMark :: Yes  = recover_question_mark { 
351+         if  RecoverQuestionMark :: Yes  = = recover_question_mark { 
334352            ty = self . maybe_recover_from_question_mark ( ty) ; 
335353        } 
354+         if  recover_anon_enum == RecoverAnonEnum :: Yes 
355+             && self . check_noexpect ( & token:: BinOp ( token:: Or ) ) 
356+             && self . look_ahead ( 1 ,  |t| t. can_begin_type ( ) ) 
357+         { 
358+             let  mut  pipes = vec ! [ self . token. span] ; 
359+             let  mut  types = vec ! [ ty] ; 
360+             loop  { 
361+                 if  !self . eat ( & token:: BinOp ( token:: Or ) )  { 
362+                     break ; 
363+                 } 
364+                 pipes. push ( self . prev_token . span ) ; 
365+                 types. push ( self . parse_ty_common ( 
366+                     allow_plus, 
367+                     allow_c_variadic, 
368+                     recover_qpath, 
369+                     recover_return_sign, 
370+                     ty_generics, 
371+                     recover_question_mark, 
372+                     RecoverAnonEnum :: No , 
373+                 ) ?) ; 
374+             } 
375+             let  mut  err = self . struct_span_err ( pipes,  "anonymous enums are not supported" ) ; 
376+             for  ty in  & types { 
377+                 err. span_label ( ty. span ,  "" ) ; 
378+             } 
379+             err. help ( & format ! ( 
380+                 "create a named `enum` and use it here instead:\n enum Name {{\n {}\n }}" , 
381+                 types
382+                     . iter( ) 
383+                     . enumerate( ) 
384+                     . map( |( i,  t) | format!( 
385+                         "    Variant{}({})," , 
386+                         i + 1 ,  // Lets not confuse people with zero-indexing :) 
387+                         pprust:: to_string( |s| s. print_type( & t) ) , 
388+                     ) ) 
389+                     . collect:: <Vec <_>>( ) 
390+                     . join( "\n " ) , 
391+             ) ) ; 
392+             err. emit ( ) ; 
393+             return  Ok ( self . mk_ty ( lo. to ( self . prev_token . span ) ,  TyKind :: AnonEnum ( types) ) ) ; 
394+         } 
336395        if  allow_qpath_recovery {  self . maybe_recover_from_bad_qpath ( ty)  }  else  {  Ok ( ty)  } 
337396    } 
338397
0 commit comments