@@ -15,8 +15,9 @@ use rustc_hir::def::{CtorOf, DefKind, Res};
15
15
use rustc_hir:: pat_util:: EnumerateAndAdjustIterator ;
16
16
use rustc_hir:: RangeEnd ;
17
17
use rustc_index:: vec:: Idx ;
18
- use rustc_middle:: mir:: interpret:: { get_slice_bytes, ConstValue } ;
19
- use rustc_middle:: mir:: interpret:: { ErrorHandled , LitToConstError , LitToConstInput } ;
18
+ use rustc_middle:: mir:: interpret:: {
19
+ ConstValue , ErrorHandled , LitToConstError , LitToConstInput , Scalar ,
20
+ } ;
20
21
use rustc_middle:: mir:: { self , UserTypeProjection } ;
21
22
use rustc_middle:: mir:: { BorrowKind , Field , Mutability } ;
22
23
use rustc_middle:: thir:: { Ascription , BindingMode , FieldPat , LocalVarId , Pat , PatKind , PatRange } ;
@@ -129,7 +130,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
129
130
) -> PatKind < ' tcx > {
130
131
assert_eq ! ( lo. ty( ) , ty) ;
131
132
assert_eq ! ( hi. ty( ) , ty) ;
132
- let cmp = compare_const_vals ( self . tcx , lo, hi, self . param_env , ty ) ;
133
+ let cmp = compare_const_vals ( self . tcx , lo, hi, self . param_env ) ;
133
134
match ( end, cmp) {
134
135
// `x..y` where `x < y`.
135
136
// Non-empty because the range includes at least `x`.
@@ -753,57 +754,49 @@ pub(crate) fn compare_const_vals<'tcx>(
753
754
a : mir:: ConstantKind < ' tcx > ,
754
755
b : mir:: ConstantKind < ' tcx > ,
755
756
param_env : ty:: ParamEnv < ' tcx > ,
756
- ty : Ty < ' tcx > ,
757
757
) -> Option < Ordering > {
758
- let from_bool = |v : bool | v. then_some ( Ordering :: Equal ) ;
759
-
760
- let fallback = || from_bool ( a == b) ;
761
-
762
- // Use the fallback if any type differs
763
- if a. ty ( ) != b. ty ( ) || a. ty ( ) != ty {
764
- return fallback ( ) ;
765
- }
766
-
767
- if a == b {
768
- return from_bool ( true ) ;
769
- }
770
-
771
- let a_bits = a. try_eval_bits ( tcx, param_env, ty) ;
772
- let b_bits = b. try_eval_bits ( tcx, param_env, ty) ;
773
-
774
- if let ( Some ( a) , Some ( b) ) = ( a_bits, b_bits) {
775
- use rustc_apfloat:: Float ;
776
- return match * ty. kind ( ) {
777
- ty:: Float ( ty:: FloatTy :: F32 ) => {
778
- let l = rustc_apfloat:: ieee:: Single :: from_bits ( a) ;
779
- let r = rustc_apfloat:: ieee:: Single :: from_bits ( b) ;
780
- l. partial_cmp ( & r)
781
- }
782
- ty:: Float ( ty:: FloatTy :: F64 ) => {
783
- let l = rustc_apfloat:: ieee:: Double :: from_bits ( a) ;
784
- let r = rustc_apfloat:: ieee:: Double :: from_bits ( b) ;
785
- l. partial_cmp ( & r)
786
- }
787
- ty:: Int ( ity) => {
788
- use rustc_middle:: ty:: layout:: IntegerExt ;
789
- let size = rustc_target:: abi:: Integer :: from_int_ty ( & tcx, ity) . size ( ) ;
790
- let a = size. sign_extend ( a) ;
791
- let b = size. sign_extend ( b) ;
792
- Some ( ( a as i128 ) . cmp ( & ( b as i128 ) ) )
793
- }
794
- _ => Some ( a. cmp ( & b) ) ,
795
- } ;
796
- }
797
-
798
- if let ty:: Str = ty. kind ( ) && let (
799
- Some ( a_val @ ConstValue :: Slice { .. } ) ,
800
- Some ( b_val @ ConstValue :: Slice { .. } ) ,
801
- ) = ( a. try_to_value ( tcx) , b. try_to_value ( tcx) )
802
- {
803
- let a_bytes = get_slice_bytes ( & tcx, a_val) ;
804
- let b_bytes = get_slice_bytes ( & tcx, b_val) ;
805
- return from_bool ( a_bytes == b_bytes) ;
758
+ assert_eq ! ( a. ty( ) , b. ty( ) ) ;
759
+
760
+ let ty = a. ty ( ) ;
761
+
762
+ // This code is hot when compiling matches with many ranges. So we
763
+ // special-case extraction of evaluated scalars for speed, for types where
764
+ // raw data comparisons are appropriate. E.g. `unicode-normalization` has
765
+ // many ranges such as '\u{037A}'..='\u{037F}', and chars can be compared
766
+ // in this way.
767
+ match ty. kind ( ) {
768
+ ty:: Float ( _) | ty:: Int ( _) => { } // require special handling, see below
769
+ _ => match ( a, b) {
770
+ (
771
+ mir:: ConstantKind :: Val ( ConstValue :: Scalar ( Scalar :: Int ( a) ) , _a_ty) ,
772
+ mir:: ConstantKind :: Val ( ConstValue :: Scalar ( Scalar :: Int ( b) ) , _b_ty) ,
773
+ ) => return Some ( a. cmp ( & b) ) ,
774
+ _ => { }
775
+ } ,
776
+ }
777
+
778
+ let a = a. eval_bits ( tcx, param_env, ty) ;
779
+ let b = b. eval_bits ( tcx, param_env, ty) ;
780
+
781
+ use rustc_apfloat:: Float ;
782
+ match * ty. kind ( ) {
783
+ ty:: Float ( ty:: FloatTy :: F32 ) => {
784
+ let a = rustc_apfloat:: ieee:: Single :: from_bits ( a) ;
785
+ let b = rustc_apfloat:: ieee:: Single :: from_bits ( b) ;
786
+ a. partial_cmp ( & b)
787
+ }
788
+ ty:: Float ( ty:: FloatTy :: F64 ) => {
789
+ let a = rustc_apfloat:: ieee:: Double :: from_bits ( a) ;
790
+ let b = rustc_apfloat:: ieee:: Double :: from_bits ( b) ;
791
+ a. partial_cmp ( & b)
792
+ }
793
+ ty:: Int ( ity) => {
794
+ use rustc_middle:: ty:: layout:: IntegerExt ;
795
+ let size = rustc_target:: abi:: Integer :: from_int_ty ( & tcx, ity) . size ( ) ;
796
+ let a = size. sign_extend ( a) ;
797
+ let b = size. sign_extend ( b) ;
798
+ Some ( ( a as i128 ) . cmp ( & ( b as i128 ) ) )
799
+ }
800
+ _ => Some ( a. cmp ( & b) ) ,
806
801
}
807
-
808
- fallback ( )
809
802
}
0 commit comments