@@ -15,8 +15,9 @@ use rustc_hir::def::{CtorOf, DefKind, Res};
1515use rustc_hir:: pat_util:: EnumerateAndAdjustIterator ;
1616use rustc_hir:: RangeEnd ;
1717use 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+ } ;
2021use rustc_middle:: mir:: { self , UserTypeProjection } ;
2122use rustc_middle:: mir:: { BorrowKind , Field , Mutability } ;
2223use rustc_middle:: thir:: { Ascription , BindingMode , FieldPat , LocalVarId , Pat , PatKind , PatRange } ;
@@ -129,7 +130,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
129130 ) -> PatKind < ' tcx > {
130131 assert_eq ! ( lo. ty( ) , ty) ;
131132 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 ) ;
133134 match ( end, cmp) {
134135 // `x..y` where `x < y`.
135136 // Non-empty because the range includes at least `x`.
@@ -753,57 +754,49 @@ pub(crate) fn compare_const_vals<'tcx>(
753754 a : mir:: ConstantKind < ' tcx > ,
754755 b : mir:: ConstantKind < ' tcx > ,
755756 param_env : ty:: ParamEnv < ' tcx > ,
756- ty : Ty < ' tcx > ,
757757) -> 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) ) ,
806801 }
807-
808- fallback ( )
809802}
0 commit comments