Skip to content

Commit b2d1d6f

Browse files
committed
Avoid span_delayed_bug on one path in AdtDef::eval_explicit_discr.
Also change its return type to `Result`.
1 parent d0267cb commit b2d1d6f

File tree

2 files changed

+25
-14
lines changed

2 files changed

+25
-14
lines changed

compiler/rustc_hir_analysis/src/collect.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,7 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
760760
let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
761761
prev_discr = Some(
762762
if let ty::VariantDiscr::Explicit(const_def_id) = variant.discr {
763-
def.eval_explicit_discr(tcx, const_def_id)
763+
def.eval_explicit_discr(tcx, const_def_id).ok()
764764
} else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
765765
Some(discr)
766766
} else {

compiler/rustc_middle/src/ty/adt.rs

+24-13
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_data_structures::fx::FxHashMap;
77
use rustc_data_structures::intern::Interned;
88
use rustc_data_structures::stable_hasher::HashingControls;
99
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
10+
use rustc_errors::ErrorGuaranteed;
1011
use rustc_hir as hir;
1112
use rustc_hir::def::{CtorKind, DefKind, Res};
1213
use 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

Comments
 (0)