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() => {
|
ty::TyAdt(adt_def, substs) if adt_def.is_enum() => {
|
||||||
match cv.val {
|
match cv.val {
|
||||||
ConstVal::Value(val) => {
|
ConstVal::Value(val) => {
|
||||||
let discr = const_discr(
|
let discr_val = const_discr(
|
||||||
self.tcx, self.param_env, instance, val, cv.ty
|
self.tcx, self.param_env, instance, val, cv.ty
|
||||||
).unwrap();
|
).expect("const_discr failed");
|
||||||
let variant_index = adt_def
|
let layout = self
|
||||||
.discriminants(self.tcx)
|
.tcx
|
||||||
.position(|var| var.val == discr)
|
.layout_of(self.param_env.and(cv.ty))
|
||||||
.unwrap();
|
.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(
|
let subpatterns = adt_subpatterns(
|
||||||
adt_def.variants[variant_index].fields.len(),
|
adt_def.variants[variant_index].fields.len(),
|
||||||
Some(variant_index),
|
Some(variant_index),
|
||||||
|
Loading…
Reference in New Issue
Block a user