@@ -50,6 +50,7 @@ use std::ops::RangeInclusive;
5050
5151use smallvec:: { smallvec, SmallVec } ;
5252
53+ use rustc_apfloat:: ieee:: { DoubleS , IeeeFloat , SingleS } ;
5354use rustc_data_structures:: captures:: Captures ;
5455use rustc_hir:: { HirId , RangeEnd } ;
5556use rustc_index:: Idx ;
@@ -65,7 +66,6 @@ use rustc_target::abi::{FieldIdx, Integer, Size, VariantIdx, FIRST_VARIANT};
6566use self :: Constructor :: * ;
6667use self :: SliceKind :: * ;
6768
68- use super :: compare_const_vals;
6969use super :: usefulness:: { MatchCheckCtxt , PatCtxt } ;
7070use crate :: errors:: { Overlap , OverlappingRangeEndpoints } ;
7171
@@ -619,7 +619,8 @@ pub(super) enum Constructor<'tcx> {
619619 /// Ranges of integer literal values (`2`, `2..=5` or `2..5`).
620620 IntRange ( IntRange ) ,
621621 /// Ranges of floating-point literal values (`2.0..=5.2`).
622- FloatRange ( mir:: Const < ' tcx > , mir:: Const < ' tcx > , RangeEnd ) ,
622+ F32Range ( IeeeFloat < SingleS > , IeeeFloat < SingleS > , RangeEnd ) ,
623+ F64Range ( IeeeFloat < DoubleS > , IeeeFloat < DoubleS > , RangeEnd ) ,
623624 /// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
624625 Str ( mir:: Const < ' tcx > ) ,
625626 /// Array and slice patterns.
@@ -634,7 +635,9 @@ pub(super) enum Constructor<'tcx> {
634635 /// Stands for constructors that are not seen in the matrix, as explained in the documentation
635636 /// for [`SplitWildcard`]. The carried `bool` is used for the `non_exhaustive_omitted_patterns`
636637 /// lint.
637- Missing { nonexhaustive_enum_missing_real_variants : bool } ,
638+ Missing {
639+ nonexhaustive_enum_missing_real_variants : bool ,
640+ } ,
638641 /// Wildcard pattern.
639642 Wildcard ,
640643 /// Or-pattern.
@@ -722,7 +725,8 @@ impl<'tcx> Constructor<'tcx> {
722725 } ,
723726 Slice ( slice) => slice. arity ( ) ,
724727 Str ( ..)
725- | FloatRange ( ..)
728+ | F32Range ( ..)
729+ | F64Range ( ..)
726730 | IntRange ( ..)
727731 | NonExhaustive
728732 | Opaque
@@ -795,21 +799,21 @@ impl<'tcx> Constructor<'tcx> {
795799 ( Variant ( self_id) , Variant ( other_id) ) => self_id == other_id,
796800
797801 ( IntRange ( self_range) , IntRange ( other_range) ) => self_range. is_covered_by ( other_range) ,
798- (
799- FloatRange ( self_from, self_to, self_end) ,
800- FloatRange ( other_from, other_to, other_end) ,
801- ) => {
802- match (
803- compare_const_vals ( pcx. cx . tcx , * self_to, * other_to, pcx. cx . param_env ) ,
804- compare_const_vals ( pcx. cx . tcx , * self_from, * other_from, pcx. cx . param_env ) ,
805- ) {
806- ( Some ( to) , Some ( from) ) => {
807- ( from == Ordering :: Greater || from == Ordering :: Equal )
808- && ( to == Ordering :: Less
809- || ( other_end == self_end && to == Ordering :: Equal ) )
802+ ( F32Range ( self_from, self_to, self_end) , F32Range ( other_from, other_to, other_end) ) => {
803+ self_from. ge ( other_from)
804+ && match self_to. partial_cmp ( other_to) {
805+ Some ( Ordering :: Less ) => true ,
806+ Some ( Ordering :: Equal ) => other_end == self_end,
807+ _ => false ,
808+ }
809+ }
810+ ( F64Range ( self_from, self_to, self_end) , F64Range ( other_from, other_to, other_end) ) => {
811+ self_from. ge ( other_from)
812+ && match self_to. partial_cmp ( other_to) {
813+ Some ( Ordering :: Less ) => true ,
814+ Some ( Ordering :: Equal ) => other_end == self_end,
815+ _ => false ,
810816 }
811- _ => false ,
812- }
813817 }
814818 ( Str ( self_val) , Str ( other_val) ) => {
815819 // FIXME Once valtrees are available we can directly use the bytes
@@ -859,7 +863,7 @@ impl<'tcx> Constructor<'tcx> {
859863 . any ( |other| slice. is_covered_by ( other) ) ,
860864 // This constructor is never covered by anything else
861865 NonExhaustive => false ,
862- Str ( ..) | FloatRange ( ..) | Opaque | Missing { .. } | Wildcard | Or => {
866+ Str ( ..) | F32Range ( .. ) | F64Range ( ..) | Opaque | Missing { .. } | Wildcard | Or => {
863867 span_bug ! ( pcx. span, "found unexpected ctor in all_ctors: {:?}" , self )
864868 }
865869 }
@@ -1203,7 +1207,8 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
12031207 _ => bug ! ( "bad slice pattern {:?} {:?}" , constructor, pcx) ,
12041208 } ,
12051209 Str ( ..)
1206- | FloatRange ( ..)
1210+ | F32Range ( ..)
1211+ | F64Range ( ..)
12071212 | IntRange ( ..)
12081213 | NonExhaustive
12091214 | Opaque
@@ -1348,8 +1353,19 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
13481353 fields = Fields :: empty ( ) ;
13491354 } else {
13501355 match pat. ty . kind ( ) {
1351- ty:: Float ( _) => {
1352- ctor = FloatRange ( * value, * value, RangeEnd :: Included ) ;
1356+ ty:: Float ( float_ty) => {
1357+ let bits = value. eval_bits ( cx. tcx , cx. param_env ) ;
1358+ use rustc_apfloat:: Float ;
1359+ ctor = match float_ty {
1360+ ty:: FloatTy :: F32 => {
1361+ let value = rustc_apfloat:: ieee:: Single :: from_bits ( bits) ;
1362+ F32Range ( value, value, RangeEnd :: Included )
1363+ }
1364+ ty:: FloatTy :: F64 => {
1365+ let value = rustc_apfloat:: ieee:: Double :: from_bits ( bits) ;
1366+ F64Range ( value, value, RangeEnd :: Included )
1367+ }
1368+ } ;
13531369 fields = Fields :: empty ( ) ;
13541370 }
13551371 ty:: Ref ( _, t, _) if t. is_str ( ) => {
@@ -1376,17 +1392,25 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
13761392 }
13771393 }
13781394 & PatKind :: Range ( box PatRange { lo, hi, end } ) => {
1395+ use rustc_apfloat:: Float ;
13791396 let ty = lo. ty ( ) ;
1380- ctor = if let Some ( int_range) = IntRange :: from_range (
1381- cx. tcx ,
1382- lo. eval_bits ( cx. tcx , cx. param_env ) ,
1383- hi. eval_bits ( cx. tcx , cx. param_env ) ,
1384- ty,
1385- & end,
1386- ) {
1387- IntRange ( int_range)
1388- } else {
1389- FloatRange ( lo, hi, end)
1397+ let lo = lo. eval_bits ( cx. tcx , cx. param_env ) ;
1398+ let hi = hi. eval_bits ( cx. tcx , cx. param_env ) ;
1399+ ctor = match ty. kind ( ) {
1400+ ty:: Char | ty:: Int ( _) | ty:: Uint ( _) => {
1401+ IntRange ( IntRange :: from_range ( cx. tcx , lo, hi, ty, & end) . unwrap ( ) )
1402+ }
1403+ ty:: Float ( ty:: FloatTy :: F32 ) => {
1404+ let lo = rustc_apfloat:: ieee:: Single :: from_bits ( lo) ;
1405+ let hi = rustc_apfloat:: ieee:: Single :: from_bits ( hi) ;
1406+ F32Range ( lo, hi, * end)
1407+ }
1408+ ty:: Float ( ty:: FloatTy :: F64 ) => {
1409+ let lo = rustc_apfloat:: ieee:: Double :: from_bits ( lo) ;
1410+ let hi = rustc_apfloat:: ieee:: Double :: from_bits ( hi) ;
1411+ F64Range ( lo, hi, * end)
1412+ }
1413+ _ => bug ! ( "invalid type for range pattern: {}" , ty) ,
13901414 } ;
13911415 fields = Fields :: empty ( ) ;
13921416 }
@@ -1491,14 +1515,13 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
14911515 }
14921516 }
14931517 & Str ( value) => PatKind :: Constant { value } ,
1494- & FloatRange ( lo, hi, end) => PatKind :: Range ( Box :: new ( PatRange { lo, hi, end } ) ) ,
14951518 IntRange ( range) => return range. to_pat ( cx. tcx , self . ty ) ,
14961519 Wildcard | NonExhaustive => PatKind :: Wild ,
14971520 Missing { .. } => bug ! (
14981521 "trying to convert a `Missing` constructor into a `Pat`; this is probably a bug,
14991522 `Missing` should have been processed in `apply_constructors`"
15001523 ) ,
1501- Opaque | Or => {
1524+ F32Range ( .. ) | F64Range ( .. ) | Opaque | Or => {
15021525 bug ! ( "can't convert to pattern: {:?}" , self )
15031526 }
15041527 } ;
@@ -1673,11 +1696,8 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> {
16731696 }
16741697 write ! ( f, "]" )
16751698 }
1676- & FloatRange ( lo, hi, end) => {
1677- write ! ( f, "{lo}" ) ?;
1678- write ! ( f, "{end}" ) ?;
1679- write ! ( f, "{hi}" )
1680- }
1699+ F32Range ( lo, hi, end) => write ! ( f, "{lo}{end}{hi}" ) ,
1700+ F64Range ( lo, hi, end) => write ! ( f, "{lo}{end}{hi}" ) ,
16811701 IntRange ( range) => write ! ( f, "{range:?}" ) , // Best-effort, will render e.g. `false` as `0..=0`
16821702 Wildcard | Missing { .. } | NonExhaustive => write ! ( f, "_ : {:?}" , self . ty) ,
16831703 Or => {
0 commit comments