Skip to content

Commit

Permalink
Trim discriminants to their final type size
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Mar 27, 2018
1 parent a0b0f5f commit 6b3202a
Showing 1 changed file with 29 additions and 6 deletions.
35 changes: 29 additions & 6 deletions src/librustc_mir/hair/pattern/mod.rs
Expand Up @@ -851,13 +851,36 @@ 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 { dataful_variant, .. } =>
dataful_variant,
};
let subpatterns = adt_subpatterns(
adt_def.variants[variant_index].fields.len(),
Some(variant_index),
Expand Down

0 comments on commit 6b3202a

Please sign in to comment.