@@ -50,6 +50,7 @@ use std::ops::RangeInclusive;
50
50
51
51
use smallvec:: { smallvec, SmallVec } ;
52
52
53
+ use rustc_apfloat:: ieee:: { DoubleS , IeeeFloat , SingleS } ;
53
54
use rustc_data_structures:: captures:: Captures ;
54
55
use rustc_hir:: { HirId , RangeEnd } ;
55
56
use rustc_index:: Idx ;
@@ -65,7 +66,6 @@ use rustc_target::abi::{FieldIdx, Integer, Size, VariantIdx, FIRST_VARIANT};
65
66
use self :: Constructor :: * ;
66
67
use self :: SliceKind :: * ;
67
68
68
- use super :: compare_const_vals;
69
69
use super :: usefulness:: { MatchCheckCtxt , PatCtxt } ;
70
70
use crate :: errors:: { Overlap , OverlappingRangeEndpoints } ;
71
71
@@ -619,7 +619,8 @@ pub(super) enum Constructor<'tcx> {
619
619
/// Ranges of integer literal values (`2`, `2..=5` or `2..5`).
620
620
IntRange ( IntRange ) ,
621
621
/// 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 ) ,
623
624
/// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
624
625
Str ( mir:: Const < ' tcx > ) ,
625
626
/// Array and slice patterns.
@@ -634,7 +635,9 @@ pub(super) enum Constructor<'tcx> {
634
635
/// Stands for constructors that are not seen in the matrix, as explained in the documentation
635
636
/// for [`SplitWildcard`]. The carried `bool` is used for the `non_exhaustive_omitted_patterns`
636
637
/// lint.
637
- Missing { nonexhaustive_enum_missing_real_variants : bool } ,
638
+ Missing {
639
+ nonexhaustive_enum_missing_real_variants : bool ,
640
+ } ,
638
641
/// Wildcard pattern.
639
642
Wildcard ,
640
643
/// Or-pattern.
@@ -722,7 +725,8 @@ impl<'tcx> Constructor<'tcx> {
722
725
} ,
723
726
Slice ( slice) => slice. arity ( ) ,
724
727
Str ( ..)
725
- | FloatRange ( ..)
728
+ | F32Range ( ..)
729
+ | F64Range ( ..)
726
730
| IntRange ( ..)
727
731
| NonExhaustive
728
732
| Opaque
@@ -795,21 +799,21 @@ impl<'tcx> Constructor<'tcx> {
795
799
( Variant ( self_id) , Variant ( other_id) ) => self_id == other_id,
796
800
797
801
( 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 ,
810
816
}
811
- _ => false ,
812
- }
813
817
}
814
818
( Str ( self_val) , Str ( other_val) ) => {
815
819
// FIXME Once valtrees are available we can directly use the bytes
@@ -859,7 +863,7 @@ impl<'tcx> Constructor<'tcx> {
859
863
. any ( |other| slice. is_covered_by ( other) ) ,
860
864
// This constructor is never covered by anything else
861
865
NonExhaustive => false ,
862
- Str ( ..) | FloatRange ( ..) | Opaque | Missing { .. } | Wildcard | Or => {
866
+ Str ( ..) | F32Range ( .. ) | F64Range ( ..) | Opaque | Missing { .. } | Wildcard | Or => {
863
867
span_bug ! ( pcx. span, "found unexpected ctor in all_ctors: {:?}" , self )
864
868
}
865
869
}
@@ -1203,7 +1207,8 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
1203
1207
_ => bug ! ( "bad slice pattern {:?} {:?}" , constructor, pcx) ,
1204
1208
} ,
1205
1209
Str ( ..)
1206
- | FloatRange ( ..)
1210
+ | F32Range ( ..)
1211
+ | F64Range ( ..)
1207
1212
| IntRange ( ..)
1208
1213
| NonExhaustive
1209
1214
| Opaque
@@ -1348,8 +1353,19 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
1348
1353
fields = Fields :: empty ( ) ;
1349
1354
} else {
1350
1355
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
+ } ;
1353
1369
fields = Fields :: empty ( ) ;
1354
1370
}
1355
1371
ty:: Ref ( _, t, _) if t. is_str ( ) => {
@@ -1376,17 +1392,25 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
1376
1392
}
1377
1393
}
1378
1394
& PatKind :: Range ( box PatRange { lo, hi, end } ) => {
1395
+ use rustc_apfloat:: Float ;
1379
1396
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) ,
1390
1414
} ;
1391
1415
fields = Fields :: empty ( ) ;
1392
1416
}
@@ -1491,14 +1515,13 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
1491
1515
}
1492
1516
}
1493
1517
& Str ( value) => PatKind :: Constant { value } ,
1494
- & FloatRange ( lo, hi, end) => PatKind :: Range ( Box :: new ( PatRange { lo, hi, end } ) ) ,
1495
1518
IntRange ( range) => return range. to_pat ( cx. tcx , self . ty ) ,
1496
1519
Wildcard | NonExhaustive => PatKind :: Wild ,
1497
1520
Missing { .. } => bug ! (
1498
1521
"trying to convert a `Missing` constructor into a `Pat`; this is probably a bug,
1499
1522
`Missing` should have been processed in `apply_constructors`"
1500
1523
) ,
1501
- Opaque | Or => {
1524
+ F32Range ( .. ) | F64Range ( .. ) | Opaque | Or => {
1502
1525
bug ! ( "can't convert to pattern: {:?}" , self )
1503
1526
}
1504
1527
} ;
@@ -1673,11 +1696,8 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> {
1673
1696
}
1674
1697
write ! ( f, "]" )
1675
1698
}
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}" ) ,
1681
1701
IntRange ( range) => write ! ( f, "{range:?}" ) , // Best-effort, will render e.g. `false` as `0..=0`
1682
1702
Wildcard | Missing { .. } | NonExhaustive => write ! ( f, "_ : {:?}" , self . ty) ,
1683
1703
Or => {
0 commit comments