Change:
Originally found by when experimenting with discriminants starting from 1 in modify labels: +regression-from-stable-to-stable +I-unsound
After a quick it appears that the regression appear with Rust 1.48.0
A bisection seems to lead to , nightly 2020-09-26 from to
Assigning priority as discussed in the of the Prioritization Working Group. label -I-prioritize +P-critical
Looks like it is mostly likely caused by which is supposed to cc

Discussion:
impl<'tcx> MirPass<'tcx> for SimplifyBranchSame { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { <ins> // This optimization is disabled by default for now due to // soundness concerns; see issue #89485 and PR #89489. if !tcx.sess.opts.debugging_opts.unsound_mir_opts { return; } </ins> trace!("Running SimplifyBranchSame on {:?}", body.source); let finder = SimplifyBranchSameOptimizationFinder { body, tcx }; let opts = finder.find();

let helper = |rhs: &Rvalue<'tcx>, place: &Place<'tcx>, variant_index: &VariantIdx, <ins> switch_value: u128, </ins> side_to_choose| { let place_type = place.ty(self.body, self.tcx).ty; let adt = match *place_type.kind() { ty::Adt(adt, _) if adt.is_enum() => adt, _ => return StatementEquality::NotEqual, }; <ins> // We need to make sure that the switch value that targets the bb with // SetDiscriminant is the same as the variant discriminant. let variant_discr = adt.discriminant_for_variant(self.tcx, *variant_index).val; if variant_discr != switch_value { trace!( "NO: variant discriminant {} does not equal switch value {}", variant_discr, switch_value ); return StatementEquality::NotEqual; } </ins> let variant_is_fieldless = adt.variants[*variant_index].fields.is_empty(); if !variant_is_fieldless { trace!("NO: variant {:?} was not fieldless", variant_index);

( StatementKind::Assign(box (_, rhs)), StatementKind::SetDiscriminant { place, variant_index }, <del> ) // we need to make sure that the switch value that targets the bb with SetDiscriminant (y), is the same as the variant index if Some(variant_index.index() as u128) == y_target_and_value.value => { </del> <ins> ) if y_target_and_value.value.is_some() => { </ins> // choose basic block of x, as that has the assign <del> helper(rhs, place, variant_index, x_target_and_value.target) </del> <ins> helper( rhs, place, variant_index, y_target_and_value.value.unwrap(), x_target_and_value.target, ) </ins> } ( StatementKind::SetDiscriminant { place, variant_index }, StatementKind::Assign(box (_, rhs)), <del> ) // we need to make sure that the switch value that targets the bb with SetDiscriminant (x), is the same as the variant index if Some(variant_index.index() as u128) == x_target_and_value.value  => { </del> <ins> ) if x_target_and_value.value.is_some() => { </ins> // choose basic block of y, as that has the assign <del> helper(rhs, place, variant_index, y_target_and_value.target) </del> <ins> helper( rhs, place, variant_index, x_target_and_value.value.unwrap(), y_target_and_value.target, ) </ins> } _ => { trace!("NO: statements `{:?}` and `{:?}` not considered equal", x, y);

<ins> // Regression test for issue #89485. // run-pass #[derive(Debug, Eq, PartialEq)] pub enum Type { A = 1, B = 2, } pub fn encode(v: Type) -> Type { match v { Type::A => Type::B, _ => v, } } fn main() { assert_eq!(Type::B, encode(Type::A)); } </ins>