@@ -832,15 +832,18 @@ pub enum PatKind<'tcx> {
832832 } ,
833833
834834 /// One of the following:
835- /// * `&str` (represented as a valtree) , which will be handled as a string pattern and thus
835+ /// * `&str`, which will be handled as a string pattern and thus
836836 /// exhaustiveness checking will detect if you use the same string twice in different
837837 /// patterns.
838- /// * integer, bool, char or float (represented as a valtree) , which will be handled by
838+ /// * integer, bool, char or float, which will be handled by
839839 /// exhaustiveness to cover exactly its own value, similar to `&str`, but these values are
840840 /// much simpler.
841841 /// * `String`, if `string_deref_patterns` is enabled.
842842 Constant {
843- value : mir:: Const < ' tcx > ,
843+ // Not using `ty::Value` since this is conceptually not a type-level constant. In
844+ // particular, it can have raw pointers.
845+ ty : Ty < ' tcx > ,
846+ value : ty:: ValTree < ' tcx > ,
844847 } ,
845848
846849 /// Pattern obtained by converting a constant (inline or named) to its pattern
@@ -932,17 +935,17 @@ impl<'tcx> PatRange<'tcx> {
932935 // Also, for performance, it's important to only do the second `try_to_bits` if necessary.
933936 let lo_is_min = match self . lo {
934937 PatRangeBoundary :: NegInfinity => true ,
935- PatRangeBoundary :: Finite ( value) => {
936- let lo = value. try_to_bits ( size ) . unwrap ( ) ^ bias;
938+ PatRangeBoundary :: Finite ( _ty , value) => {
939+ let lo = value. unwrap_leaf ( ) . to_bits ( size ) ^ bias;
937940 lo <= min
938941 }
939942 PatRangeBoundary :: PosInfinity => false ,
940943 } ;
941944 if lo_is_min {
942945 let hi_is_max = match self . hi {
943946 PatRangeBoundary :: NegInfinity => false ,
944- PatRangeBoundary :: Finite ( value) => {
945- let hi = value. try_to_bits ( size ) . unwrap ( ) ^ bias;
947+ PatRangeBoundary :: Finite ( _ty , value) => {
948+ let hi = value. unwrap_leaf ( ) . to_bits ( size ) ^ bias;
946949 hi > max || hi == max && self . end == RangeEnd :: Included
947950 }
948951 PatRangeBoundary :: PosInfinity => true ,
@@ -955,22 +958,16 @@ impl<'tcx> PatRange<'tcx> {
955958 }
956959
957960 #[ inline]
958- pub fn contains (
959- & self ,
960- value : mir:: Const < ' tcx > ,
961- tcx : TyCtxt < ' tcx > ,
962- typing_env : ty:: TypingEnv < ' tcx > ,
963- ) -> Option < bool > {
961+ pub fn contains ( & self , value : ty:: ValTree < ' tcx > , tcx : TyCtxt < ' tcx > ) -> Option < bool > {
964962 use Ordering :: * ;
965- debug_assert_eq ! ( self . ty, value. ty( ) ) ;
966963 let ty = self . ty ;
967- let value = PatRangeBoundary :: Finite ( value) ;
964+ let value = PatRangeBoundary :: Finite ( ty , value) ;
968965 // For performance, it's important to only do the second comparison if necessary.
969966 Some (
970- match self . lo . compare_with ( value, ty, tcx, typing_env ) ? {
967+ match self . lo . compare_with ( value, ty, tcx) ? {
971968 Less | Equal => true ,
972969 Greater => false ,
973- } && match value. compare_with ( self . hi , ty, tcx, typing_env ) ? {
970+ } && match value. compare_with ( self . hi , ty, tcx) ? {
974971 Less => true ,
975972 Equal => self . end == RangeEnd :: Included ,
976973 Greater => false ,
@@ -979,21 +976,16 @@ impl<'tcx> PatRange<'tcx> {
979976 }
980977
981978 #[ inline]
982- pub fn overlaps (
983- & self ,
984- other : & Self ,
985- tcx : TyCtxt < ' tcx > ,
986- typing_env : ty:: TypingEnv < ' tcx > ,
987- ) -> Option < bool > {
979+ pub fn overlaps ( & self , other : & Self , tcx : TyCtxt < ' tcx > ) -> Option < bool > {
988980 use Ordering :: * ;
989981 debug_assert_eq ! ( self . ty, other. ty) ;
990982 // For performance, it's important to only do the second comparison if necessary.
991983 Some (
992- match other. lo . compare_with ( self . hi , self . ty , tcx, typing_env ) ? {
984+ match other. lo . compare_with ( self . hi , self . ty , tcx) ? {
993985 Less => true ,
994986 Equal => self . end == RangeEnd :: Included ,
995987 Greater => false ,
996- } && match self . lo . compare_with ( other. hi , self . ty , tcx, typing_env ) ? {
988+ } && match self . lo . compare_with ( other. hi , self . ty , tcx) ? {
997989 Less => true ,
998990 Equal => other. end == RangeEnd :: Included ,
999991 Greater => false ,
@@ -1004,10 +996,13 @@ impl<'tcx> PatRange<'tcx> {
1004996
1005997impl < ' tcx > fmt:: Display for PatRange < ' tcx > {
1006998 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1007- if let PatRangeBoundary :: Finite ( value) = & self . lo {
999+ if let & PatRangeBoundary :: Finite ( ty, value) = & self . lo {
1000+ // `ty::Value` has a reasonable pretty-printing implementation.
1001+ let value = ty:: Value { ty, valtree : value } ;
10081002 write ! ( f, "{value}" ) ?;
10091003 }
1010- if let PatRangeBoundary :: Finite ( value) = & self . hi {
1004+ if let & PatRangeBoundary :: Finite ( ty, value) = & self . hi {
1005+ let value = ty:: Value { ty, valtree : value } ;
10111006 write ! ( f, "{}" , self . end) ?;
10121007 write ! ( f, "{value}" ) ?;
10131008 } else {
@@ -1022,7 +1017,7 @@ impl<'tcx> fmt::Display for PatRange<'tcx> {
10221017/// If present, the const must be of a numeric type.
10231018#[ derive( Copy , Clone , Debug , PartialEq , HashStable , TypeVisitable ) ]
10241019pub enum PatRangeBoundary < ' tcx > {
1025- Finite ( mir :: Const < ' tcx > ) ,
1020+ Finite ( Ty < ' tcx > , ty :: ValTree < ' tcx > ) ,
10261021 NegInfinity ,
10271022 PosInfinity ,
10281023}
@@ -1033,20 +1028,15 @@ impl<'tcx> PatRangeBoundary<'tcx> {
10331028 matches ! ( self , Self :: Finite ( ..) )
10341029 }
10351030 #[ inline]
1036- pub fn as_finite ( self ) -> Option < mir :: Const < ' tcx > > {
1031+ pub fn as_finite ( self ) -> Option < ty :: ValTree < ' tcx > > {
10371032 match self {
1038- Self :: Finite ( value) => Some ( value) ,
1033+ Self :: Finite ( _ty , value) => Some ( value) ,
10391034 Self :: NegInfinity | Self :: PosInfinity => None ,
10401035 }
10411036 }
1042- pub fn eval_bits (
1043- self ,
1044- ty : Ty < ' tcx > ,
1045- tcx : TyCtxt < ' tcx > ,
1046- typing_env : ty:: TypingEnv < ' tcx > ,
1047- ) -> u128 {
1037+ pub fn eval_bits ( self , ty : Ty < ' tcx > , tcx : TyCtxt < ' tcx > ) -> u128 {
10481038 match self {
1049- Self :: Finite ( value) => value. eval_bits ( tcx , typing_env ) ,
1039+ Self :: Finite ( _ty , value) => value. unwrap_leaf ( ) . to_bits_unchecked ( ) ,
10501040 Self :: NegInfinity => {
10511041 // Unwrap is ok because the type is known to be numeric.
10521042 ty. numeric_min_and_max_as_bits ( tcx) . unwrap ( ) . 0
@@ -1058,14 +1048,8 @@ impl<'tcx> PatRangeBoundary<'tcx> {
10581048 }
10591049 }
10601050
1061- #[ instrument( skip( tcx, typing_env) , level = "debug" , ret) ]
1062- pub fn compare_with (
1063- self ,
1064- other : Self ,
1065- ty : Ty < ' tcx > ,
1066- tcx : TyCtxt < ' tcx > ,
1067- typing_env : ty:: TypingEnv < ' tcx > ,
1068- ) -> Option < Ordering > {
1051+ #[ instrument( skip( tcx) , level = "debug" , ret) ]
1052+ pub fn compare_with ( self , other : Self , ty : Ty < ' tcx > , tcx : TyCtxt < ' tcx > ) -> Option < Ordering > {
10691053 use PatRangeBoundary :: * ;
10701054 match ( self , other) {
10711055 // When comparing with infinities, we must remember that `0u8..` and `0u8..=255`
@@ -1079,7 +1063,9 @@ impl<'tcx> PatRangeBoundary<'tcx> {
10791063 // we can do scalar comparisons. E.g. `unicode-normalization` has
10801064 // many ranges such as '\u{037A}'..='\u{037F}', and chars can be compared
10811065 // in this way.
1082- ( Finite ( a) , Finite ( b) ) if matches ! ( ty. kind( ) , ty:: Int ( _) | ty:: Uint ( _) | ty:: Char ) => {
1066+ ( Finite ( _, a) , Finite ( _, b) )
1067+ if matches ! ( ty. kind( ) , ty:: Int ( _) | ty:: Uint ( _) | ty:: Char ) =>
1068+ {
10831069 if let ( Some ( a) , Some ( b) ) = ( a. try_to_scalar_int ( ) , b. try_to_scalar_int ( ) ) {
10841070 let sz = ty. primitive_size ( tcx) ;
10851071 let cmp = match ty. kind ( ) {
@@ -1093,8 +1079,8 @@ impl<'tcx> PatRangeBoundary<'tcx> {
10931079 _ => { }
10941080 }
10951081
1096- let a = self . eval_bits ( ty, tcx, typing_env ) ;
1097- let b = other. eval_bits ( ty, tcx, typing_env ) ;
1082+ let a = self . eval_bits ( ty, tcx) ;
1083+ let b = other. eval_bits ( ty, tcx) ;
10981084
10991085 match ty. kind ( ) {
11001086 ty:: Float ( ty:: FloatTy :: F16 ) => {
0 commit comments