diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index eb87d5b044b45..798d635318180 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -851,13 +851,38 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ty::TyAdt(adt_def, substs) if adt_def.is_enum() => { match cv.val { ConstVal::Value(val) => { - let discr = const_discr( + let discr_val = const_discr( self.tcx, self.param_env, instance, val, cv.ty - ).unwrap(); - let variant_index = adt_def - .discriminants(self.tcx) - .position(|var| var.val == discr) - .unwrap(); + ).expect("const_discr failed"); + let layout = self + .tcx + .layout_of(self.param_env.and(cv.ty)) + .expect("layout of enum not available"); + let variant_index = match layout.variants { + ty::layout::Variants::Single { index } => index, + ty::layout::Variants::Tagged { ref discr, .. } => { + // raw discriminants for enums are isize or bigger during + // their computation, but later shrunk to the smallest possible + // representation + let size = discr.value.size(self.tcx).bits(); + let amt = 128 - size; + adt_def + .discriminants(self.tcx) + .position(|var| ((var.val << amt) >> amt) == discr_val) + .unwrap_or_else(|| { + bug!("discriminant {} not found in {:#?}", + discr_val, + adt_def + .discriminants(self.tcx) + .collect::>(), + ); + }) + } + ty::layout::Variants::NicheFilling { .. } => { + assert_eq!(discr_val as usize as u128, discr_val); + discr_val as usize + }, + }; let subpatterns = adt_subpatterns( adt_def.variants[variant_index].fields.len(), Some(variant_index), diff --git a/src/test/run-pass/match-arm-statics.rs b/src/test/run-pass/match-arm-statics.rs index 78a37f5183786..ca6ef2e42777b 100644 --- a/src/test/run-pass/match-arm-statics.rs +++ b/src/test/run-pass/match-arm-statics.rs @@ -94,6 +94,13 @@ fn issue_14576() { const F : C = C::D; assert_eq!(match C::D { F => 1, _ => 2, }, 1); + + // test gaps + #[derive(PartialEq, Eq)] + enum G { H = 3, I = 5 } + const K : G = G::I; + + assert_eq!(match G::I { K => 1, _ => 2, }, 1); } fn issue_13731() {