Trim discriminants to their final type size
This commit is contained in:
parent
a0b0f5fba5
commit
6b3202a2bf
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user