@@ -11,6 +11,7 @@ use rustc_ast::{
11
11
self as ast, BareFnTy , FnRetTy , GenericBound , GenericBounds , GenericParam , Generics , Lifetime ,
12
12
MacCall , MutTy , Mutability , PolyTraitRef , TraitBoundModifier , TraitObjectSyntax , Ty , TyKind ,
13
13
} ;
14
+ use rustc_ast_pretty:: pprust;
14
15
use rustc_errors:: { pluralize, struct_span_err, Applicability , PResult } ;
15
16
use rustc_span:: source_map:: Span ;
16
17
use rustc_span:: symbol:: { kw, sym, Ident } ;
@@ -43,17 +44,24 @@ pub(super) enum AllowPlus {
43
44
No ,
44
45
}
45
46
46
- #[ derive( PartialEq ) ]
47
+ #[ derive( PartialEq , Clone , Copy ) ]
47
48
pub ( super ) enum RecoverQPath {
48
49
Yes ,
49
50
No ,
50
51
}
51
52
53
+ #[ derive( PartialEq , Clone , Copy ) ]
52
54
pub ( super ) enum RecoverQuestionMark {
53
55
Yes ,
54
56
No ,
55
57
}
56
58
59
+ #[ derive( PartialEq , Clone , Copy ) ]
60
+ pub ( super ) enum RecoverAnonEnum {
61
+ Yes ,
62
+ No ,
63
+ }
64
+
57
65
/// Signals whether parsing a type should recover `->`.
58
66
///
59
67
/// More specifically, when parsing a function like:
@@ -86,7 +94,7 @@ impl RecoverReturnSign {
86
94
}
87
95
88
96
// Is `...` (`CVarArgs`) legal at this level of type parsing?
89
- #[ derive( PartialEq ) ]
97
+ #[ derive( PartialEq , Clone , Copy ) ]
90
98
enum AllowCVariadic {
91
99
Yes ,
92
100
No ,
@@ -111,6 +119,7 @@ impl<'a> Parser<'a> {
111
119
RecoverReturnSign :: Yes ,
112
120
None ,
113
121
RecoverQuestionMark :: Yes ,
122
+ RecoverAnonEnum :: No ,
114
123
)
115
124
}
116
125
@@ -125,6 +134,7 @@ impl<'a> Parser<'a> {
125
134
RecoverReturnSign :: Yes ,
126
135
Some ( ty_params) ,
127
136
RecoverQuestionMark :: Yes ,
137
+ RecoverAnonEnum :: No ,
128
138
)
129
139
}
130
140
@@ -139,6 +149,7 @@ impl<'a> Parser<'a> {
139
149
RecoverReturnSign :: Yes ,
140
150
None ,
141
151
RecoverQuestionMark :: Yes ,
152
+ RecoverAnonEnum :: Yes ,
142
153
)
143
154
}
144
155
@@ -156,6 +167,7 @@ impl<'a> Parser<'a> {
156
167
RecoverReturnSign :: Yes ,
157
168
None ,
158
169
RecoverQuestionMark :: Yes ,
170
+ RecoverAnonEnum :: No ,
159
171
)
160
172
}
161
173
@@ -169,6 +181,7 @@ impl<'a> Parser<'a> {
169
181
RecoverReturnSign :: Yes ,
170
182
None ,
171
183
RecoverQuestionMark :: No ,
184
+ RecoverAnonEnum :: No ,
172
185
)
173
186
}
174
187
@@ -180,6 +193,7 @@ impl<'a> Parser<'a> {
180
193
RecoverReturnSign :: Yes ,
181
194
None ,
182
195
RecoverQuestionMark :: No ,
196
+ RecoverAnonEnum :: No ,
183
197
)
184
198
}
185
199
@@ -192,6 +206,7 @@ impl<'a> Parser<'a> {
192
206
RecoverReturnSign :: OnlyFatArrow ,
193
207
None ,
194
208
RecoverQuestionMark :: Yes ,
209
+ RecoverAnonEnum :: No ,
195
210
)
196
211
}
197
212
@@ -211,6 +226,7 @@ impl<'a> Parser<'a> {
211
226
recover_return_sign,
212
227
None ,
213
228
RecoverQuestionMark :: Yes ,
229
+ RecoverAnonEnum :: Yes ,
214
230
) ?;
215
231
FnRetTy :: Ty ( ty)
216
232
} else if recover_return_sign. can_recover ( & self . token . kind ) {
@@ -232,6 +248,7 @@ impl<'a> Parser<'a> {
232
248
recover_return_sign,
233
249
None ,
234
250
RecoverQuestionMark :: Yes ,
251
+ RecoverAnonEnum :: Yes ,
235
252
) ?;
236
253
FnRetTy :: Ty ( ty)
237
254
} else {
@@ -247,6 +264,7 @@ impl<'a> Parser<'a> {
247
264
recover_return_sign : RecoverReturnSign ,
248
265
ty_generics : Option < & Generics > ,
249
266
recover_question_mark : RecoverQuestionMark ,
267
+ recover_anon_enum : RecoverAnonEnum ,
250
268
) -> PResult < ' a , P < Ty > > {
251
269
let allow_qpath_recovery = recover_qpath == RecoverQPath :: Yes ;
252
270
maybe_recover_from_interpolated_ty_qpath ! ( self , allow_qpath_recovery) ;
@@ -325,14 +343,55 @@ impl<'a> Parser<'a> {
325
343
let mut ty = self . mk_ty ( span, kind) ;
326
344
327
345
// Try to recover from use of `+` with incorrect priority.
328
- if matches ! ( allow_plus, AllowPlus :: Yes ) {
346
+ if allow_plus == AllowPlus :: Yes {
329
347
self . maybe_recover_from_bad_type_plus ( & ty) ?;
330
348
} else {
331
349
self . maybe_report_ambiguous_plus ( impl_dyn_multi, & ty) ;
332
350
}
333
- if let RecoverQuestionMark :: Yes = recover_question_mark {
351
+ if RecoverQuestionMark :: Yes = = recover_question_mark {
334
352
ty = self . maybe_recover_from_question_mark ( ty) ;
335
353
}
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 :: Err ) ) ;
394
+ }
336
395
if allow_qpath_recovery { self . maybe_recover_from_bad_qpath ( ty) } else { Ok ( ty) }
337
396
}
338
397
0 commit comments