@@ -411,6 +411,23 @@ fn check_type_defn<'tcx, F>(
411411 ObligationCauseCode :: MiscObligation ,
412412 )
413413 }
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+ }
414431 }
415432
416433 check_where_clauses ( tcx, fcx, item. span , def_id. to_def_id ( ) , None ) ;
@@ -1287,8 +1304,14 @@ impl ParItemLikeVisitor<'tcx> for CheckTypeWellFormedVisitor<'tcx> {
12871304///////////////////////////////////////////////////////////////////////////
12881305// ADT
12891306
1307+ // FIXME(eddyb) replace this with getting fields/discriminants through `ty::AdtDef`.
12901308struct AdtVariant < ' tcx > {
1309+ /// Types of fields in the variant, that must be well-formed.
12911310 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 > ,
12921315}
12931316
12941317struct AdtField < ' tcx > {
@@ -1297,6 +1320,7 @@ struct AdtField<'tcx> {
12971320}
12981321
12991322impl < ' a , ' tcx > FnCtxt < ' a , ' tcx > {
1323+ // FIXME(eddyb) replace this with getting fields through `ty::AdtDef`.
13001324 fn non_enum_variant ( & self , struct_def : & hir:: VariantData < ' _ > ) -> AdtVariant < ' tcx > {
13011325 let fields = struct_def
13021326 . fields ( )
@@ -1309,11 +1333,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13091333 AdtField { ty : field_ty, span : field. span }
13101334 } )
13111335 . collect ( ) ;
1312- AdtVariant { fields }
1336+ AdtVariant { fields, explicit_discr : None }
13131337 }
13141338
13151339 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 ( )
13171350 }
13181351
13191352 fn impl_implied_bounds ( & self , impl_def_id : DefId , span : Span ) -> Vec < Ty < ' tcx > > {
0 commit comments