@@ -7,6 +7,7 @@ use rustc_data_structures::fx::FxHashMap;
7
7
use rustc_data_structures:: intern:: Interned ;
8
8
use rustc_data_structures:: stable_hasher:: HashingControls ;
9
9
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
10
+ use rustc_errors:: ErrorGuaranteed ;
10
11
use rustc_hir as hir;
11
12
use rustc_hir:: def:: { CtorKind , DefKind , Res } ;
12
13
use rustc_hir:: def_id:: DefId ;
@@ -475,7 +476,11 @@ impl<'tcx> AdtDef<'tcx> {
475
476
}
476
477
477
478
#[ 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 > {
479
484
assert ! ( self . is_enum( ) ) ;
480
485
let param_env = tcx. param_env ( expr_did) ;
481
486
let repr_type = self . repr ( ) . discr_type ( ) ;
@@ -484,22 +489,24 @@ impl<'tcx> AdtDef<'tcx> {
484
489
let ty = repr_type. to_ty ( tcx) ;
485
490
if let Some ( b) = val. try_to_bits_for_ty ( tcx, param_env, ty) {
486
491
trace ! ( "discriminants: {} ({:?})" , b, repr_type) ;
487
- Some ( Discr { val : b, ty } )
492
+ Ok ( Discr { val : b, ty } )
488
493
} else {
489
494
info ! ( "invalid enum discriminant: {:#?}" , val) ;
490
- tcx. dcx ( ) . emit_err ( crate :: error:: ConstEvalNonIntError {
495
+ let guar = tcx. dcx ( ) . emit_err ( crate :: error:: ConstEvalNonIntError {
491
496
span : tcx. def_span ( expr_did) ,
492
497
} ) ;
493
- None
498
+ Err ( guar )
494
499
}
495
500
}
496
501
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
+ ) ,
500
508
} ;
501
- tcx. dcx ( ) . span_delayed_bug ( tcx. def_span ( expr_did) , msg) ;
502
- None
509
+ Err ( guar)
503
510
}
504
511
}
505
512
}
@@ -516,7 +523,7 @@ impl<'tcx> AdtDef<'tcx> {
516
523
self . variants ( ) . iter_enumerated ( ) . map ( move |( i, v) | {
517
524
let mut discr = prev_discr. map_or ( initial, |d| d. wrap_incr ( tcx) ) ;
518
525
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) {
520
527
discr = new_discr;
521
528
}
522
529
}
@@ -544,9 +551,13 @@ impl<'tcx> AdtDef<'tcx> {
544
551
) -> Discr < ' tcx > {
545
552
assert ! ( self . is_enum( ) ) ;
546
553
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
+ } ;
550
561
explicit_value. checked_add ( tcx, offset as u128 ) . 0
551
562
}
552
563
0 commit comments