@@ -584,7 +584,6 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
584
584
-> Vec < Constructor < ' tcx > >
585
585
{
586
586
debug ! ( "all_constructors({:?})" , pcx. ty) ;
587
- let exhaustive_integer_patterns = cx. tcx . features ( ) . exhaustive_integer_patterns ;
588
587
let ctors = match pcx. ty . sty {
589
588
ty:: Bool => {
590
589
[ true , false ] . iter ( ) . map ( |& b| {
@@ -614,7 +613,7 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
614
613
. map ( |v| Variant ( v. did ) )
615
614
. collect ( )
616
615
}
617
- ty:: Char if exhaustive_integer_patterns => {
616
+ ty:: Char => {
618
617
vec ! [
619
618
// The valid Unicode Scalar Value ranges.
620
619
ConstantRange ( '\u{0000}' as u128 ,
@@ -629,14 +628,14 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
629
628
) ,
630
629
]
631
630
}
632
- ty:: Int ( ity) if exhaustive_integer_patterns => {
631
+ ty:: Int ( ity) => {
633
632
// FIXME(49937): refactor these bit manipulations into interpret.
634
633
let bits = Integer :: from_attr ( & cx. tcx , SignedInt ( ity) ) . size ( ) . bits ( ) as u128 ;
635
634
let min = 1u128 << ( bits - 1 ) ;
636
635
let max = ( 1u128 << ( bits - 1 ) ) - 1 ;
637
636
vec ! [ ConstantRange ( min, max, pcx. ty, RangeEnd :: Included ) ]
638
637
}
639
- ty:: Uint ( uty) if exhaustive_integer_patterns => {
638
+ ty:: Uint ( uty) => {
640
639
// FIXME(49937): refactor these bit manipulations into interpret.
641
640
let bits = Integer :: from_attr ( & cx. tcx , UnsignedInt ( uty) ) . size ( ) . bits ( ) as u128 ;
642
641
let max = !0u128 >> ( 128 - bits) ;
@@ -775,8 +774,17 @@ impl<'tcx> IntRange<'tcx> {
775
774
fn from_ctor ( tcx : TyCtxt < ' _ , ' tcx , ' tcx > ,
776
775
ctor : & Constructor < ' tcx > )
777
776
-> Option < IntRange < ' tcx > > {
777
+ // Floating-point ranges are permitted and we don't want
778
+ // to consider them when constructing integer ranges.
779
+ fn is_integral < ' tcx > ( ty : Ty < ' tcx > ) -> bool {
780
+ match ty. sty {
781
+ ty:: Char | ty:: Int ( _) | ty:: Uint ( _) => true ,
782
+ _ => false ,
783
+ }
784
+ }
785
+
778
786
match ctor {
779
- ConstantRange ( lo, hi, ty, end) => {
787
+ ConstantRange ( lo, hi, ty, end) if is_integral ( ty ) => {
780
788
// Perform a shift if the underlying types are signed,
781
789
// which makes the interval arithmetic simpler.
782
790
let bias = IntRange :: signed_bias ( tcx, ty) ;
@@ -789,7 +797,7 @@ impl<'tcx> IntRange<'tcx> {
789
797
Some ( IntRange { range : lo..=( hi - offset) , ty } )
790
798
}
791
799
}
792
- ConstantValue ( val) => {
800
+ ConstantValue ( val) if is_integral ( val . ty ) => {
793
801
let ty = val. ty ;
794
802
if let Some ( val) = val. assert_bits ( tcx, ty:: ParamEnv :: empty ( ) . and ( ty) ) {
795
803
let bias = IntRange :: signed_bias ( tcx, ty) ;
@@ -799,9 +807,7 @@ impl<'tcx> IntRange<'tcx> {
799
807
None
800
808
}
801
809
}
802
- Single | Variant ( _) | Slice ( _) => {
803
- None
804
- }
810
+ _ => None ,
805
811
}
806
812
}
807
813
@@ -933,12 +939,10 @@ fn compute_missing_ctors<'a, 'tcx: 'a>(
933
939
// If a constructor appears in a `match` arm, we can
934
940
// eliminate it straight away.
935
941
refined_ctors = vec ! [ ]
936
- } else if tcx. features ( ) . exhaustive_integer_patterns {
937
- if let Some ( interval) = IntRange :: from_ctor ( tcx, used_ctor) {
938
- // Refine the required constructors for the type by subtracting
939
- // the range defined by the current constructor pattern.
940
- refined_ctors = interval. subtract_from ( tcx, refined_ctors) ;
941
- }
942
+ } else if let Some ( interval) = IntRange :: from_ctor ( tcx, used_ctor) {
943
+ // Refine the required constructors for the type by subtracting
944
+ // the range defined by the current constructor pattern.
945
+ refined_ctors = interval. subtract_from ( tcx, refined_ctors) ;
942
946
}
943
947
944
948
// If the constructor patterns that have been considered so far
@@ -1094,7 +1098,8 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
1094
1098
1095
1099
// For privately empty and non-exhaustive enums, we work as if there were an "extra"
1096
1100
// `_` constructor for the type, so we can never match over all constructors.
1097
- let is_non_exhaustive = is_privately_empty || is_declared_nonexhaustive;
1101
+ let is_non_exhaustive = is_privately_empty || is_declared_nonexhaustive ||
1102
+ ( pcx. ty . is_pointer_sized ( ) && !cx. tcx . features ( ) . precise_pointer_size_matching ) ;
1098
1103
1099
1104
if cheap_missing_ctors == MissingCtors :: Empty && !is_non_exhaustive {
1100
1105
split_grouped_constructors ( cx. tcx , all_ctors, matrix, pcx. ty ) . into_iter ( ) . map ( |c| {
@@ -1390,17 +1395,16 @@ fn slice_pat_covered_by_constructor<'tcx>(
1390
1395
// Whether to evaluate a constructor using exhaustive integer matching. This is true if the
1391
1396
// constructor is a range or constant with an integer type.
1392
1397
fn should_treat_range_exhaustively ( tcx : TyCtxt < ' _ , ' tcx , ' tcx > , ctor : & Constructor < ' tcx > ) -> bool {
1393
- if tcx . features ( ) . exhaustive_integer_patterns {
1394
- let ty = match ctor {
1395
- ConstantValue ( value ) => value . ty ,
1396
- ConstantRange ( _ , _ , ty , _ ) => ty ,
1397
- _ => return false ,
1398
- } ;
1399
- if let ty :: Char | ty :: Int ( _ ) | ty :: Uint ( _ ) = ty . sty {
1400
- return true ;
1401
- }
1398
+ let ty = match ctor {
1399
+ ConstantValue ( value ) => value . ty ,
1400
+ ConstantRange ( _ , _ , ty , _ ) => ty,
1401
+ _ => return false ,
1402
+ } ;
1403
+ if let ty :: Char | ty :: Int ( _ ) | ty :: Uint ( _ ) = ty . sty {
1404
+ !ty . is_pointer_sized ( ) || tcx . features ( ) . precise_pointer_size_matching
1405
+ } else {
1406
+ false
1402
1407
}
1403
- false
1404
1408
}
1405
1409
1406
1410
/// For exhaustive integer matching, some constructors are grouped within other constructors
0 commit comments