@@ -411,6 +411,23 @@ fn check_type_defn<'tcx, F>(
411
411
ObligationCauseCode :: MiscObligation ,
412
412
)
413
413
}
414
+
415
+ // Explicit `enum` discriminant values must const-evaluate successfully.
416
+ if let Some ( discr_def_id) = variant. explicit_discr {
417
+ let discr_substs =
418
+ InternalSubsts :: identity_for_item ( fcx. tcx , discr_def_id. to_def_id ( ) ) ;
419
+
420
+ let cause = traits:: ObligationCause :: new (
421
+ fcx. tcx . def_span ( discr_def_id) ,
422
+ fcx. body_id ,
423
+ traits:: MiscObligation ,
424
+ ) ;
425
+ fcx. register_predicate ( traits:: Obligation :: new (
426
+ cause,
427
+ fcx. param_env ,
428
+ ty:: Predicate :: ConstEvaluatable ( discr_def_id. to_def_id ( ) , discr_substs) ,
429
+ ) ) ;
430
+ }
414
431
}
415
432
416
433
check_where_clauses ( tcx, fcx, item. span , def_id. to_def_id ( ) , None ) ;
@@ -1287,8 +1304,14 @@ impl ParItemLikeVisitor<'tcx> for CheckTypeWellFormedVisitor<'tcx> {
1287
1304
///////////////////////////////////////////////////////////////////////////
1288
1305
// ADT
1289
1306
1307
+ // FIXME(eddyb) replace this with getting fields/discriminants through `ty::AdtDef`.
1290
1308
struct AdtVariant < ' tcx > {
1309
+ /// Types of fields in the variant, that must be well-formed.
1291
1310
fields : Vec < AdtField < ' tcx > > ,
1311
+
1312
+ /// Explicit discriminant of this variant (e.g. `A = 123`),
1313
+ /// that must evaluate to a constant value.
1314
+ explicit_discr : Option < LocalDefId > ,
1292
1315
}
1293
1316
1294
1317
struct AdtField < ' tcx > {
@@ -1297,6 +1320,7 @@ struct AdtField<'tcx> {
1297
1320
}
1298
1321
1299
1322
impl < ' a , ' tcx > FnCtxt < ' a , ' tcx > {
1323
+ // FIXME(eddyb) replace this with getting fields through `ty::AdtDef`.
1300
1324
fn non_enum_variant ( & self , struct_def : & hir:: VariantData < ' _ > ) -> AdtVariant < ' tcx > {
1301
1325
let fields = struct_def
1302
1326
. fields ( )
@@ -1309,11 +1333,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1309
1333
AdtField { ty : field_ty, span : field. span }
1310
1334
} )
1311
1335
. collect ( ) ;
1312
- AdtVariant { fields }
1336
+ AdtVariant { fields, explicit_discr : None }
1313
1337
}
1314
1338
1315
1339
fn enum_variants ( & self , enum_def : & hir:: EnumDef < ' _ > ) -> Vec < AdtVariant < ' tcx > > {
1316
- enum_def. variants . iter ( ) . map ( |variant| self . non_enum_variant ( & variant. data ) ) . collect ( )
1340
+ enum_def
1341
+ . variants
1342
+ . iter ( )
1343
+ . map ( |variant| AdtVariant {
1344
+ fields : self . non_enum_variant ( & variant. data ) . fields ,
1345
+ explicit_discr : variant
1346
+ . disr_expr
1347
+ . map ( |explicit_discr| self . tcx . hir ( ) . local_def_id ( explicit_discr. hir_id ) ) ,
1348
+ } )
1349
+ . collect ( )
1317
1350
}
1318
1351
1319
1352
fn impl_implied_bounds ( & self , impl_def_id : DefId , span : Span ) -> Vec < Ty < ' tcx > > {
0 commit comments