@@ -584,7 +584,6 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
584584 -> Vec < Constructor < ' tcx > >
585585{
586586 debug ! ( "all_constructors({:?})" , pcx. ty) ;
587- let exhaustive_integer_patterns = cx. tcx . features ( ) . exhaustive_integer_patterns ;
588587 let ctors = match pcx. ty . sty {
589588 ty:: Bool => {
590589 [ true , false ] . iter ( ) . map ( |& b| {
@@ -614,7 +613,7 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
614613 . map ( |v| Variant ( v. did ) )
615614 . collect ( )
616615 }
617- ty:: Char if exhaustive_integer_patterns => {
616+ ty:: Char => {
618617 vec ! [
619618 // The valid Unicode Scalar Value ranges.
620619 ConstantRange ( '\u{0000}' as u128 ,
@@ -629,14 +628,14 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
629628 ) ,
630629 ]
631630 }
632- ty:: Int ( ity) if exhaustive_integer_patterns => {
631+ ty:: Int ( ity) => {
633632 // FIXME(49937): refactor these bit manipulations into interpret.
634633 let bits = Integer :: from_attr ( & cx. tcx , SignedInt ( ity) ) . size ( ) . bits ( ) as u128 ;
635634 let min = 1u128 << ( bits - 1 ) ;
636635 let max = ( 1u128 << ( bits - 1 ) ) - 1 ;
637636 vec ! [ ConstantRange ( min, max, pcx. ty, RangeEnd :: Included ) ]
638637 }
639- ty:: Uint ( uty) if exhaustive_integer_patterns => {
638+ ty:: Uint ( uty) => {
640639 // FIXME(49937): refactor these bit manipulations into interpret.
641640 let bits = Integer :: from_attr ( & cx. tcx , UnsignedInt ( uty) ) . size ( ) . bits ( ) as u128 ;
642641 let max = !0u128 >> ( 128 - bits) ;
@@ -775,8 +774,17 @@ impl<'tcx> IntRange<'tcx> {
775774 fn from_ctor ( tcx : TyCtxt < ' _ , ' tcx , ' tcx > ,
776775 ctor : & Constructor < ' tcx > )
777776 -> 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+
778786 match ctor {
779- ConstantRange ( lo, hi, ty, end) => {
787+ ConstantRange ( lo, hi, ty, end) if is_integral ( ty ) => {
780788 // Perform a shift if the underlying types are signed,
781789 // which makes the interval arithmetic simpler.
782790 let bias = IntRange :: signed_bias ( tcx, ty) ;
@@ -789,7 +797,7 @@ impl<'tcx> IntRange<'tcx> {
789797 Some ( IntRange { range : lo..=( hi - offset) , ty } )
790798 }
791799 }
792- ConstantValue ( val) => {
800+ ConstantValue ( val) if is_integral ( val . ty ) => {
793801 let ty = val. ty ;
794802 if let Some ( val) = val. assert_bits ( tcx, ty:: ParamEnv :: empty ( ) . and ( ty) ) {
795803 let bias = IntRange :: signed_bias ( tcx, ty) ;
@@ -799,9 +807,7 @@ impl<'tcx> IntRange<'tcx> {
799807 None
800808 }
801809 }
802- Single | Variant ( _) | Slice ( _) => {
803- None
804- }
810+ _ => None ,
805811 }
806812 }
807813
@@ -933,12 +939,10 @@ fn compute_missing_ctors<'a, 'tcx: 'a>(
933939 // If a constructor appears in a `match` arm, we can
934940 // eliminate it straight away.
935941 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) ;
942946 }
943947
944948 // 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>,
10941098
10951099 // For privately empty and non-exhaustive enums, we work as if there were an "extra"
10961100 // `_` 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 ) ;
10981103
10991104 if cheap_missing_ctors == MissingCtors :: Empty && !is_non_exhaustive {
11001105 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>(
13901395// Whether to evaluate a constructor using exhaustive integer matching. This is true if the
13911396// constructor is a range or constant with an integer type.
13921397fn 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
14021407 }
1403- false
14041408}
14051409
14061410/// For exhaustive integer matching, some constructors are grouped within other constructors
0 commit comments