Skip to content

Commit 6b3202a

Browse files
committed
Trim discriminants to their final type size
1 parent a0b0f5f commit 6b3202a

File tree

1 file changed

+29
-6
lines changed
  • src/librustc_mir/hair/pattern

1 file changed

+29
-6
lines changed

src/librustc_mir/hair/pattern/mod.rs

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -851,13 +851,36 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
851851
ty::TyAdt(adt_def, substs) if adt_def.is_enum() => {
852852
match cv.val {
853853
ConstVal::Value(val) => {
854-
let discr = const_discr(
854+
let discr_val = const_discr(
855855
self.tcx, self.param_env, instance, val, cv.ty
856-
).unwrap();
857-
let variant_index = adt_def
858-
.discriminants(self.tcx)
859-
.position(|var| var.val == discr)
860-
.unwrap();
856+
).expect("const_discr failed");
857+
let layout = self
858+
.tcx
859+
.layout_of(self.param_env.and(cv.ty))
860+
.expect("layout of enum not available");
861+
let variant_index = match layout.variants {
862+
ty::layout::Variants::Single { index } => index,
863+
ty::layout::Variants::Tagged { ref discr, .. } => {
864+
// raw discriminants for enums are isize or bigger during
865+
// their computation, but later shrunk to the smallest possible
866+
// representation
867+
let size = discr.value.size(self.tcx).bits();
868+
let amt = 128 - size;
869+
adt_def
870+
.discriminants(self.tcx)
871+
.position(|var| ((var.val << amt) >> amt) == discr_val)
872+
.unwrap_or_else(|| {
873+
bug!("discriminant {} not found in {:#?}",
874+
discr_val,
875+
adt_def
876+
.discriminants(self.tcx)
877+
.collect::<Vec<_>>(),
878+
);
879+
})
880+
}
881+
ty::layout::Variants::NicheFilling { dataful_variant, .. } =>
882+
dataful_variant,
883+
};
861884
let subpatterns = adt_subpatterns(
862885
adt_def.variants[variant_index].fields.len(),
863886
Some(variant_index),

0 commit comments

Comments
 (0)