@@ -7,6 +7,7 @@ use rustc_data_structures::fx::FxHashMap;
77use rustc_data_structures:: intern:: Interned ;
88use rustc_data_structures:: stable_hasher:: HashingControls ;
99use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
10+ use rustc_errors:: ErrorGuaranteed ;
1011use rustc_hir as hir;
1112use rustc_hir:: def:: { CtorKind , DefKind , Res } ;
1213use rustc_hir:: def_id:: DefId ;
@@ -475,7 +476,11 @@ impl<'tcx> AdtDef<'tcx> {
475476 }
476477
477478 #[ inline]
478- pub fn eval_explicit_discr ( self , tcx : TyCtxt < ' tcx > , expr_did : DefId ) -> Option < Discr < ' tcx > > {
479+ pub fn eval_explicit_discr (
480+ self ,
481+ tcx : TyCtxt < ' tcx > ,
482+ expr_did : DefId ,
483+ ) -> Result < Discr < ' tcx > , ErrorGuaranteed > {
479484 assert ! ( self . is_enum( ) ) ;
480485 let param_env = tcx. param_env ( expr_did) ;
481486 let repr_type = self . repr ( ) . discr_type ( ) ;
@@ -484,22 +489,24 @@ impl<'tcx> AdtDef<'tcx> {
484489 let ty = repr_type. to_ty ( tcx) ;
485490 if let Some ( b) = val. try_to_bits_for_ty ( tcx, param_env, ty) {
486491 trace ! ( "discriminants: {} ({:?})" , b, repr_type) ;
487- Some ( Discr { val : b, ty } )
492+ Ok ( Discr { val : b, ty } )
488493 } else {
489494 info ! ( "invalid enum discriminant: {:#?}" , val) ;
490- tcx. dcx ( ) . emit_err ( crate :: error:: ConstEvalNonIntError {
495+ let guar = tcx. dcx ( ) . emit_err ( crate :: error:: ConstEvalNonIntError {
491496 span : tcx. def_span ( expr_did) ,
492497 } ) ;
493- None
498+ Err ( guar )
494499 }
495500 }
496501 Err ( err) => {
497- let msg = match err {
498- ErrorHandled :: Reported ( ..) => "enum discriminant evaluation failed" ,
499- ErrorHandled :: TooGeneric ( ..) => "enum discriminant depends on generics" ,
502+ let guar = match err {
503+ ErrorHandled :: Reported ( info, _) => info. into ( ) ,
504+ ErrorHandled :: TooGeneric ( ..) => tcx. dcx ( ) . span_delayed_bug (
505+ tcx. def_span ( expr_did) ,
506+ "enum discriminant depends on generics" ,
507+ ) ,
500508 } ;
501- tcx. dcx ( ) . span_delayed_bug ( tcx. def_span ( expr_did) , msg) ;
502- None
509+ Err ( guar)
503510 }
504511 }
505512 }
@@ -516,7 +523,7 @@ impl<'tcx> AdtDef<'tcx> {
516523 self . variants ( ) . iter_enumerated ( ) . map ( move |( i, v) | {
517524 let mut discr = prev_discr. map_or ( initial, |d| d. wrap_incr ( tcx) ) ;
518525 if let VariantDiscr :: Explicit ( expr_did) = v. discr {
519- if let Some ( new_discr) = self . eval_explicit_discr ( tcx, expr_did) {
526+ if let Ok ( new_discr) = self . eval_explicit_discr ( tcx, expr_did) {
520527 discr = new_discr;
521528 }
522529 }
@@ -544,9 +551,13 @@ impl<'tcx> AdtDef<'tcx> {
544551 ) -> Discr < ' tcx > {
545552 assert ! ( self . is_enum( ) ) ;
546553 let ( val, offset) = self . discriminant_def_for_variant ( variant_index) ;
547- let explicit_value = val
548- . and_then ( |expr_did| self . eval_explicit_discr ( tcx, expr_did) )
549- . unwrap_or_else ( || self . repr ( ) . discr_type ( ) . initial_discriminant ( tcx) ) ;
554+ let explicit_value = if let Some ( expr_did) = val
555+ && let Ok ( val) = self . eval_explicit_discr ( tcx, expr_did)
556+ {
557+ val
558+ } else {
559+ self . repr ( ) . discr_type ( ) . initial_discriminant ( tcx)
560+ } ;
550561 explicit_value. checked_add ( tcx, offset as u128 ) . 0
551562 }
552563
0 commit comments