@@ -49,11 +49,10 @@ use super::usefulness::{MatchCheckCtxt, PatCtxt};
49
49
50
50
use rustc_apfloat:: ieee:: { DoubleS , IeeeFloat , SingleS } ;
51
51
use rustc_data_structures:: captures:: Captures ;
52
- use rustc_index:: vec:: Idx ;
53
52
54
53
use rustc_hir:: { HirId , RangeEnd } ;
55
54
use rustc_middle:: ty:: subst:: GenericArg ;
56
- use rustc_middle:: ty:: { self , Ty } ;
55
+ use rustc_middle:: ty:: Ty ;
57
56
use rustc_span:: { Span , DUMMY_SP } ;
58
57
use rustc_target:: abi:: VariantIdx ;
59
58
@@ -93,16 +92,6 @@ impl IntRange {
93
92
( * self . range . start ( ) , * self . range . end ( ) )
94
93
}
95
94
96
- // The return value of `signed_bias` should be XORed with an endpoint to encode/decode it.
97
- #[ inline]
98
- fn signed_bias ( ty : Ty < ' _ > , ty_size : rustc_target:: abi:: Size ) -> u128 {
99
- match * ty. kind ( ) {
100
- ty:: Int ( _) => 1u128 << ( ty_size. bits ( ) as u128 - 1 ) ,
101
- ty:: Char | ty:: Uint ( _) => 0 ,
102
- _ => bug ! ( "invalid type for `IntRange`: {}" , ty) ,
103
- }
104
- }
105
-
106
95
#[ inline]
107
96
pub ( super ) fn from_bits < ' tcx > (
108
97
ty : Ty < ' tcx > ,
@@ -111,7 +100,11 @@ impl IntRange {
111
100
hi : u128 ,
112
101
end : & RangeEnd ,
113
102
) -> IntRange {
114
- let bias = IntRange :: signed_bias ( ty, ty_size) ;
103
+ let bias = if MatchCheckCtxt :: is_signed_int ( ty) {
104
+ 1u128 << ( ty_size. bits ( ) as u128 - 1 )
105
+ } else {
106
+ 0
107
+ } ;
115
108
// Perform a shift if the underlying types are signed,
116
109
// which makes the interval arithmetic simpler.
117
110
let ( lo, hi) = ( lo ^ bias, hi ^ bias) ;
@@ -555,7 +548,7 @@ pub(super) enum Constructor<'tcx> {
555
548
/// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
556
549
Str ( & ' tcx [ u8 ] ) ,
557
550
/// Array and slice patterns.
558
- Slice ( Slice ) ,
551
+ Slice ( Slice , Ty < ' tcx > ) ,
559
552
/// Constants that must not be matched structurally. They are treated as black
560
553
/// boxes for the purposes of exhaustiveness: we must not inspect them, and they
561
554
/// don't count towards making a match exhaustive.
@@ -593,36 +586,19 @@ impl<'tcx> Constructor<'tcx> {
593
586
594
587
fn as_slice ( & self ) -> Option < Slice > {
595
588
match self {
596
- Slice ( slice) => Some ( * slice) ,
589
+ Slice ( slice, _ ) => Some ( * slice) ,
597
590
_ => None ,
598
591
}
599
592
}
600
593
601
- pub ( super ) fn variant_index_for_adt ( & self , adt : & ' tcx ty:: AdtDef ) -> VariantIdx {
602
- match * self {
603
- Variant ( idx) => idx,
604
- Single => {
605
- assert ! ( !adt. is_enum( ) ) ;
606
- VariantIdx :: new ( 0 )
607
- }
608
- _ => bug ! ( "bad constructor {:?} for adt {:?}" , self , adt) ,
609
- }
610
- }
611
-
612
594
/// The number of fields for this constructor. This must be kept in sync with
613
595
/// `Fields::wildcards`.
614
596
pub ( super ) fn arity ( & self , pcx : PatCtxt < ' _ , ' _ , ' tcx > ) -> usize {
615
597
match self {
616
- Single | Variant ( _) => match pcx. ty . kind ( ) {
617
- ty:: Adt ( adt, ..) => {
618
- let variant = & adt. variants [ self . variant_index_for_adt ( adt) ] ;
619
- pcx. cx . list_variant_nonhidden_fields ( pcx. ty , variant) . count ( )
620
- }
621
- _ => bug ! ( "Unexpected type for `Single` constructor: {:?}" , pcx. ty) ,
622
- } ,
598
+ Single | Variant ( _) => pcx. cx . list_variant_nonhidden_fields ( pcx. ty , self ) . count ( ) ,
623
599
Tuple ( fs) => fs. len ( ) ,
624
600
Ref ( _) | BoxPat ( _) => 1 ,
625
- Slice ( slice) => slice. arity ( ) ,
601
+ Slice ( slice, _ ) => slice. arity ( ) ,
626
602
Str ( ..)
627
603
| Bool ( ..)
628
604
| IntRange ( ..)
@@ -671,11 +647,11 @@ impl<'tcx> Constructor<'tcx> {
671
647
split_range. split ( int_ranges. cloned ( ) ) ;
672
648
split_range. iter ( ) . map ( IntRange ) . collect ( )
673
649
}
674
- & Slice ( Slice { kind : VarLen ( self_prefix, self_suffix) , array_len } ) => {
650
+ & Slice ( Slice { kind : VarLen ( self_prefix, self_suffix) , array_len } , ty ) => {
675
651
let mut split_self = SplitVarLenSlice :: new ( self_prefix, self_suffix, array_len) ;
676
652
let slices = ctors. filter_map ( |c| c. as_slice ( ) ) . map ( |s| s. kind ) ;
677
653
split_self. split ( slices) ;
678
- split_self. iter ( ) . map ( Slice ) . collect ( )
654
+ split_self. iter ( ) . map ( |s| Slice ( s , ty ) ) . collect ( )
679
655
}
680
656
// Any other constructor can be used unchanged.
681
657
_ => smallvec ! [ self . clone( ) ] ,
@@ -724,7 +700,7 @@ impl<'tcx> Constructor<'tcx> {
724
700
}
725
701
}
726
702
( Str ( self_val) , Str ( other_val) ) => self_val == other_val,
727
- ( Slice ( self_slice) , Slice ( other_slice) ) => self_slice. is_covered_by ( * other_slice) ,
703
+ ( Slice ( self_slice, _ ) , Slice ( other_slice, _ ) ) => self_slice. is_covered_by ( * other_slice) ,
728
704
729
705
// We are trying to inspect an opaque constant. Thus we skip the row.
730
706
( Opaque , _) | ( _, Opaque ) => false ,
@@ -765,7 +741,7 @@ impl<'tcx> Constructor<'tcx> {
765
741
. iter ( )
766
742
. filter_map ( |c| c. as_int_range ( ) )
767
743
. any ( |other| range. is_covered_by ( other) ) ,
768
- Slice ( slice) => used_ctors
744
+ Slice ( slice, _ ) => used_ctors
769
745
. iter ( )
770
746
. filter_map ( |c| c. as_slice ( ) )
771
747
. any ( |other| slice. is_covered_by ( other) ) ,
@@ -866,8 +842,7 @@ impl<'tcx> SplitWildcard<'tcx> {
866
842
//
867
843
// The exception is: if we are at the top-level, for example in an empty match, we
868
844
// sometimes prefer reporting the list of constructors instead of just `_`.
869
- let report_when_all_missing = pcx. is_top_level
870
- && !matches ! ( pcx. ty. kind( ) , ty:: Bool | ty:: Char | ty:: Int ( _) | ty:: Uint ( _) ) ;
845
+ let report_when_all_missing = pcx. is_top_level && !MatchCheckCtxt :: is_numeric ( pcx. ty ) ;
871
846
let ctor = if !self . matrix_ctors . is_empty ( ) || report_when_all_missing {
872
847
if pcx. is_non_exhaustive {
873
848
Missing {
@@ -953,23 +928,16 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
953
928
constructor : & Constructor < ' tcx > ,
954
929
) -> Self {
955
930
let ret = match constructor {
956
- Single | Variant ( _) => match ty. kind ( ) {
957
- ty:: Adt ( adt, _) => {
958
- let variant = & adt. variants [ constructor. variant_index_for_adt ( adt) ] ;
959
- let tys = cx. list_variant_nonhidden_fields ( ty, variant) . map ( |( _, ty) | ty) ;
960
- Fields :: wildcards_from_tys ( cx, tys)
961
- }
962
- _ => bug ! ( "Unexpected type for `Single` constructor: {:?}" , ty) ,
963
- } ,
931
+ Single | Variant ( _) => {
932
+ let tys = cx. list_variant_nonhidden_fields ( ty, constructor) . map ( |( _, ty) | ty) ;
933
+ Fields :: wildcards_from_tys ( cx, tys)
934
+ }
964
935
Tuple ( fs) => Fields :: wildcards_from_tys ( cx, fs. iter ( ) . map ( |ty| ty. expect_ty ( ) ) ) ,
965
936
Ref ( ty) | BoxPat ( ty) => Fields :: wildcards_from_tys ( cx, once ( * ty) ) ,
966
- Slice ( slice) => match * ty. kind ( ) {
967
- ty:: Slice ( ty) | ty:: Array ( ty, _) => {
968
- let arity = slice. arity ( ) ;
969
- Fields :: wildcards_from_tys ( cx, ( 0 ..arity) . map ( |_| ty) )
970
- }
971
- _ => bug ! ( "bad slice pattern {:?} {:?}" , constructor, ty) ,
972
- } ,
937
+ Slice ( slice, ty) => {
938
+ let arity = slice. arity ( ) ;
939
+ Fields :: wildcards_from_tys ( cx, ( 0 ..arity) . map ( |_| * ty) )
940
+ }
973
941
Str ( ..)
974
942
| Bool ( ..)
975
943
| IntRange ( ..)
@@ -1068,7 +1036,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
1068
1036
// We return a wildcard for each field of `other_ctor`.
1069
1037
Fields :: wildcards ( cx, self . ty , other_ctor) . iter_patterns ( ) . collect ( )
1070
1038
}
1071
- ( Slice ( self_slice) , Slice ( other_slice) )
1039
+ ( Slice ( self_slice, inner_ty ) , Slice ( other_slice, _ ) )
1072
1040
if self_slice. arity ( ) != other_slice. arity ( ) =>
1073
1041
{
1074
1042
// The only tricky case: two slices of different arity. Since `self_slice` covers
@@ -1079,10 +1047,6 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
1079
1047
match self_slice. kind {
1080
1048
FixedLen ( _) => bug ! ( "{:?} doesn't cover {:?}" , self_slice, other_slice) ,
1081
1049
VarLen ( prefix, suffix) => {
1082
- let inner_ty = match * self . ty . kind ( ) {
1083
- ty:: Slice ( ty) | ty:: Array ( ty, _) => ty,
1084
- _ => bug ! ( "bad slice pattern {:?} {:?}" , self . ctor, self . ty) ,
1085
- } ;
1086
1050
let prefix = & self . fields . fields [ ..prefix] ;
1087
1051
let suffix = & self . fields . fields [ self_slice. arity ( ) - suffix..] ;
1088
1052
let wildcard: & _ =
@@ -1143,14 +1107,8 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> {
1143
1107
1144
1108
match & self . ctor {
1145
1109
Single | Variant ( _) | Tuple ( _) => {
1146
- let variant = match self . ty . kind ( ) {
1147
- ty:: Adt ( adt, _) => Some ( & adt. variants [ self . ctor . variant_index_for_adt ( adt) ] ) ,
1148
- ty:: Tuple ( _) => None ,
1149
- _ => unreachable ! ( ) ,
1150
- } ;
1151
-
1152
- if let Some ( variant) = variant {
1153
- write ! ( f, "{}" , variant. ident) ?;
1110
+ if let Some ( ident) = MatchCheckCtxt :: variant_ident ( self . ty ( ) , self . ctor ( ) ) {
1111
+ write ! ( f, "{}" , ident) ?;
1154
1112
}
1155
1113
1156
1114
// Without `cx`, we can't know which field corresponds to which, so we can't
@@ -1171,7 +1129,7 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> {
1171
1129
let subpattern = self . iter_fields ( ) . next ( ) . unwrap ( ) ;
1172
1130
write ! ( f, "box {:?}" , subpattern)
1173
1131
}
1174
- Slice ( slice) => {
1132
+ Slice ( slice, _ ) => {
1175
1133
let mut subpatterns = self . fields . iter_patterns ( ) ;
1176
1134
write ! ( f, "[" ) ?;
1177
1135
match slice. kind {
0 commit comments