@@ -851,13 +851,38 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
851
851
ty:: TyAdt ( adt_def, substs) if adt_def. is_enum ( ) => {
852
852
match cv. val {
853
853
ConstVal :: Value ( val) => {
854
- let discr = const_discr (
854
+ let discr_val = const_discr (
855
855
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 { .. } => {
882
+ assert_eq ! ( discr_val as usize as u128 , discr_val) ;
883
+ discr_val as usize
884
+ } ,
885
+ } ;
861
886
let subpatterns = adt_subpatterns (
862
887
adt_def. variants [ variant_index] . fields . len ( ) ,
863
888
Some ( variant_index) ,
0 commit comments