@@ -5,14 +5,14 @@ use super::builtin_attrs::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
5
5
6
6
use crate :: ast:: {
7
7
self , AssocTyConstraint , AssocTyConstraintKind , NodeId , GenericParam , GenericParamKind ,
8
- PatKind , RangeEnd ,
8
+ PatKind , RangeEnd , VariantData ,
9
9
} ;
10
10
use crate :: attr:: { self , check_builtin_attribute} ;
11
11
use crate :: source_map:: Spanned ;
12
12
use crate :: edition:: { ALL_EDITIONS , Edition } ;
13
13
use crate :: visit:: { self , FnKind , Visitor } ;
14
- use crate :: parse:: { token, ParseSess } ;
15
- use crate :: parse :: parser :: Parser ;
14
+ use crate :: parse:: token;
15
+ use crate :: sess :: ParseSess ;
16
16
use crate :: symbol:: { Symbol , sym} ;
17
17
use crate :: tokenstream:: TokenTree ;
18
18
@@ -246,6 +246,51 @@ impl<'a> PostExpansionVisitor<'a> {
246
246
Abi :: System => { }
247
247
}
248
248
}
249
+
250
+ fn maybe_report_invalid_custom_discriminants ( & self , variants : & [ ast:: Variant ] ) {
251
+ let has_fields = variants. iter ( ) . any ( |variant| match variant. data {
252
+ VariantData :: Tuple ( ..) | VariantData :: Struct ( ..) => true ,
253
+ VariantData :: Unit ( ..) => false ,
254
+ } ) ;
255
+
256
+ let discriminant_spans = variants. iter ( ) . filter ( |variant| match variant. data {
257
+ VariantData :: Tuple ( ..) | VariantData :: Struct ( ..) => false ,
258
+ VariantData :: Unit ( ..) => true ,
259
+ } )
260
+ . filter_map ( |variant| variant. disr_expr . as_ref ( ) . map ( |c| c. value . span ) )
261
+ . collect :: < Vec < _ > > ( ) ;
262
+
263
+ if !discriminant_spans. is_empty ( ) && has_fields {
264
+ let mut err = feature_err (
265
+ self . parse_sess ,
266
+ sym:: arbitrary_enum_discriminant,
267
+ discriminant_spans. clone ( ) ,
268
+ crate :: feature_gate:: GateIssue :: Language ,
269
+ "custom discriminant values are not allowed in enums with tuple or struct variants" ,
270
+ ) ;
271
+ for sp in discriminant_spans {
272
+ err. span_label ( sp, "disallowed custom discriminant" ) ;
273
+ }
274
+ for variant in variants. iter ( ) {
275
+ match & variant. data {
276
+ VariantData :: Struct ( ..) => {
277
+ err. span_label (
278
+ variant. span ,
279
+ "struct variant defined here" ,
280
+ ) ;
281
+ }
282
+ VariantData :: Tuple ( ..) => {
283
+ err. span_label (
284
+ variant. span ,
285
+ "tuple variant defined here" ,
286
+ ) ;
287
+ }
288
+ VariantData :: Unit ( ..) => { }
289
+ }
290
+ }
291
+ err. emit ( ) ;
292
+ }
293
+ }
249
294
}
250
295
251
296
impl < ' a > Visitor < ' a > for PostExpansionVisitor < ' a > {
@@ -353,7 +398,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
353
398
354
399
let has_feature = self . features . arbitrary_enum_discriminant ;
355
400
if !has_feature && !i. span . allows_unstable ( sym:: arbitrary_enum_discriminant) {
356
- Parser :: maybe_report_invalid_custom_discriminants ( self . parse_sess , & variants) ;
401
+ self . maybe_report_invalid_custom_discriminants ( & variants) ;
357
402
}
358
403
}
359
404
0 commit comments