@@ -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,14 +799,18 @@ 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
- ) {
802
+ ( F32Range ( self_from, self_to, self_end) , F32Range ( other_from, other_to, other_end) ) => {
803
+ match ( self_to. partial_cmp ( other_to) , self_from. partial_cmp ( other_from) ) {
804
+ ( Some ( to) , Some ( from) ) => {
805
+ ( from == Ordering :: Greater || from == Ordering :: Equal )
806
+ && ( to == Ordering :: Less
807
+ || ( other_end == self_end && to == Ordering :: Equal ) )
808
+ }
809
+ _ => false ,
810
+ }
811
+ }
812
+ ( F64Range ( self_from, self_to, self_end) , F64Range ( other_from, other_to, other_end) ) => {
813
+ match ( self_to. partial_cmp ( other_to) , self_from. partial_cmp ( other_from) ) {
806
814
( Some ( to) , Some ( from) ) => {
807
815
( from == Ordering :: Greater || from == Ordering :: Equal )
808
816
&& ( to == Ordering :: Less
@@ -859,7 +867,7 @@ impl<'tcx> Constructor<'tcx> {
859
867
. any ( |other| slice. is_covered_by ( other) ) ,
860
868
// This constructor is never covered by anything else
861
869
NonExhaustive => false ,
862
- Str ( ..) | FloatRange ( ..) | Opaque | Missing { .. } | Wildcard | Or => {
870
+ Str ( ..) | F32Range ( .. ) | F64Range ( ..) | Opaque | Missing { .. } | Wildcard | Or => {
863
871
span_bug ! ( pcx. span, "found unexpected ctor in all_ctors: {:?}" , self )
864
872
}
865
873
}
@@ -1203,7 +1211,8 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
1203
1211
_ => bug ! ( "bad slice pattern {:?} {:?}" , constructor, pcx) ,
1204
1212
} ,
1205
1213
Str ( ..)
1206
- | FloatRange ( ..)
1214
+ | F32Range ( ..)
1215
+ | F64Range ( ..)
1207
1216
| IntRange ( ..)
1208
1217
| NonExhaustive
1209
1218
| Opaque
@@ -1348,8 +1357,19 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
1348
1357
fields = Fields :: empty ( ) ;
1349
1358
} else {
1350
1359
match pat. ty . kind ( ) {
1351
- ty:: Float ( _) => {
1352
- ctor = FloatRange ( * value, * value, RangeEnd :: Included ) ;
1360
+ ty:: Float ( float_ty) => {
1361
+ let bits = value. eval_bits ( cx. tcx , cx. param_env ) ;
1362
+ use rustc_apfloat:: Float ;
1363
+ ctor = match float_ty {
1364
+ ty:: FloatTy :: F32 => {
1365
+ let value = rustc_apfloat:: ieee:: Single :: from_bits ( bits) ;
1366
+ F32Range ( value, value, RangeEnd :: Included )
1367
+ }
1368
+ ty:: FloatTy :: F64 => {
1369
+ let value = rustc_apfloat:: ieee:: Double :: from_bits ( bits) ;
1370
+ F64Range ( value, value, RangeEnd :: Included )
1371
+ }
1372
+ } ;
1353
1373
fields = Fields :: empty ( ) ;
1354
1374
}
1355
1375
ty:: Ref ( _, t, _) if t. is_str ( ) => {
@@ -1376,17 +1396,25 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
1376
1396
}
1377
1397
}
1378
1398
& PatKind :: Range ( box PatRange { lo, hi, end } ) => {
1399
+ use rustc_apfloat:: Float ;
1379
1400
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)
1401
+ let lo = lo. eval_bits ( cx. tcx , cx. param_env ) ;
1402
+ let hi = hi. eval_bits ( cx. tcx , cx. param_env ) ;
1403
+ ctor = match ty. kind ( ) {
1404
+ ty:: Char | ty:: Int ( _) | ty:: Uint ( _) => {
1405
+ IntRange ( IntRange :: from_range ( cx. tcx , lo, hi, ty, & end) . unwrap ( ) )
1406
+ }
1407
+ ty:: Float ( ty:: FloatTy :: F32 ) => {
1408
+ let lo = rustc_apfloat:: ieee:: Single :: from_bits ( lo) ;
1409
+ let hi = rustc_apfloat:: ieee:: Single :: from_bits ( hi) ;
1410
+ F32Range ( lo, hi, RangeEnd :: Included )
1411
+ }
1412
+ ty:: Float ( ty:: FloatTy :: F64 ) => {
1413
+ let lo = rustc_apfloat:: ieee:: Double :: from_bits ( lo) ;
1414
+ let hi = rustc_apfloat:: ieee:: Double :: from_bits ( hi) ;
1415
+ F64Range ( lo, hi, RangeEnd :: Included )
1416
+ }
1417
+ _ => bug ! ( "invalid type for range pattern: {}" , ty) ,
1390
1418
} ;
1391
1419
fields = Fields :: empty ( ) ;
1392
1420
}
@@ -1491,14 +1519,13 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
1491
1519
}
1492
1520
}
1493
1521
& Str ( value) => PatKind :: Constant { value } ,
1494
- & FloatRange ( lo, hi, end) => PatKind :: Range ( Box :: new ( PatRange { lo, hi, end } ) ) ,
1495
1522
IntRange ( range) => return range. to_pat ( cx. tcx , self . ty ) ,
1496
1523
Wildcard | NonExhaustive => PatKind :: Wild ,
1497
1524
Missing { .. } => bug ! (
1498
1525
"trying to convert a `Missing` constructor into a `Pat`; this is probably a bug,
1499
1526
`Missing` should have been processed in `apply_constructors`"
1500
1527
) ,
1501
- Opaque | Or => {
1528
+ F32Range ( .. ) | F64Range ( .. ) | Opaque | Or => {
1502
1529
bug ! ( "can't convert to pattern: {:?}" , self )
1503
1530
}
1504
1531
} ;
@@ -1673,11 +1700,8 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> {
1673
1700
}
1674
1701
write ! ( f, "]" )
1675
1702
}
1676
- & FloatRange ( lo, hi, end) => {
1677
- write ! ( f, "{lo}" ) ?;
1678
- write ! ( f, "{end}" ) ?;
1679
- write ! ( f, "{hi}" )
1680
- }
1703
+ F32Range ( lo, hi, end) => write ! ( f, "{lo}{end}{hi}" ) ,
1704
+ F64Range ( lo, hi, end) => write ! ( f, "{lo}{end}{hi}" ) ,
1681
1705
IntRange ( range) => write ! ( f, "{range:?}" ) , // Best-effort, will render e.g. `false` as `0..=0`
1682
1706
Wildcard | Missing { .. } | NonExhaustive => write ! ( f, "_ : {:?}" , self . ty) ,
1683
1707
Or => {
0 commit comments