Skip to content

Commit

Permalink
Auto merge of #49403 - oli-obk:try2, r=eddyb
Browse files Browse the repository at this point in the history
Trim discriminants to their final type size

r? @eddyb

fixes  #49181
  • Loading branch information
bors committed Mar 30, 2018
2 parents 051050d + 422efd7 commit 4379c86
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 6 deletions.
37 changes: 31 additions & 6 deletions src/librustc_mir/hair/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
7 changes: 7 additions & 0 deletions src/test/run-pass/match-arm-statics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down

0 comments on commit 4379c86

Please sign in to comment.