Auto merge of #49403 - oli-obk:try2, r=eddyb

Trim discriminants to their final type size

r? @eddyb

fixes  #49181
This commit is contained in:
bors 2018-03-30 11:48:10 +00:00
commit 4379c86fe7
2 changed files with 38 additions and 6 deletions

View file

@ -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::<Vec<_>>(),
);
})
}
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),

View file

@ -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() {