@@ -859,6 +859,7 @@ impl<'tcx> Constructor<'tcx> {
859
859
}
860
860
861
861
/// Describes the set of all constructors for a type.
862
+ #[ derive( Debug ) ]
862
863
pub ( super ) enum ConstructorSet {
863
864
/// The type has a single constructor, e.g. `&T` or a struct.
864
865
Single ,
@@ -903,6 +904,7 @@ pub(super) enum ConstructorSet {
903
904
/// - constructors in `present` and `missing` are split for the column; in other words, they are
904
905
/// either fully included in or disjoint from each constructor in the column. This avoids
905
906
/// non-trivial intersections like between `0..10` and `5..15`.
907
+ #[ derive( Debug ) ]
906
908
struct SplitConstructorSet < ' tcx > {
907
909
present : SmallVec < [ Constructor < ' tcx > ; 1 ] > ,
908
910
missing : Vec < Constructor < ' tcx > > ,
@@ -911,8 +913,8 @@ struct SplitConstructorSet<'tcx> {
911
913
}
912
914
913
915
impl ConstructorSet {
916
+ #[ instrument( level = "debug" , skip( cx) , ret) ]
914
917
pub ( super ) fn for_ty < ' p , ' tcx > ( cx : & MatchCheckCtxt < ' p , ' tcx > , ty : Ty < ' tcx > ) -> Self {
915
- debug ! ( "ConstructorSet::for_ty({:?})" , ty) ;
916
918
let make_range =
917
919
|start, end| IntRange :: from_range ( cx. tcx , start, end, ty, RangeEnd :: Included ) ;
918
920
// This determines the set of all possible constructors for the type `ty`. For numbers,
@@ -1036,6 +1038,7 @@ impl ConstructorSet {
1036
1038
/// This is the core logical operation of exhaustiveness checking. This analyzes a column a
1037
1039
/// constructors to 1/ determine which constructors of the type (if any) are missing; 2/ split
1038
1040
/// constructors to handle non-trivial intersections e.g. on ranges or slices.
1041
+ #[ instrument( level = "debug" , skip( self , pcx, ctors) , ret) ]
1039
1042
fn split < ' a , ' tcx > (
1040
1043
& self ,
1041
1044
pcx : & PatCtxt < ' _ , ' _ , ' tcx > ,
@@ -1111,7 +1114,7 @@ impl ConstructorSet {
1111
1114
}
1112
1115
& ConstructorSet :: Slice ( array_len) => {
1113
1116
let seen_slices = seen. map ( |c| c. as_slice ( ) . unwrap ( ) ) ;
1114
- let base_slice = Slice { kind : VarLen ( 0 , 0 ) , array_len } ;
1117
+ let base_slice = Slice :: new ( array_len , VarLen ( 0 , 0 ) ) ;
1115
1118
for ( seen, splitted_slice) in base_slice. split ( seen_slices) {
1116
1119
let ctor = Slice ( splitted_slice) ;
1117
1120
match seen {
@@ -1121,12 +1124,22 @@ impl ConstructorSet {
1121
1124
}
1122
1125
}
1123
1126
ConstructorSet :: SliceOfEmpty => {
1124
- // Behaves essentially like `Single`.
1125
- let slice = Slice ( Slice :: new ( None , FixedLen ( 0 ) ) ) ;
1126
- if seen. next ( ) . is_none ( ) {
1127
- missing. push ( slice) ;
1128
- } else {
1129
- present. push ( slice) ;
1127
+ // This one is tricky because even though there's only one possible value of this
1128
+ // type (namely `[]`), slice patterns of all lengths are allowed, they're just
1129
+ // unreachable if length != 0.
1130
+ // We still gather the seen constructors in `present`, but the only slice that can
1131
+ // go in `missing` is `[]`.
1132
+ let seen_slices = seen. map ( |c| c. as_slice ( ) . unwrap ( ) ) ;
1133
+ let base_slice = Slice :: new ( None , VarLen ( 0 , 0 ) ) ;
1134
+ for ( seen, splitted_slice) in base_slice. split ( seen_slices) {
1135
+ let ctor = Slice ( splitted_slice) ;
1136
+ match seen {
1137
+ Presence :: Seen => present. push ( ctor) ,
1138
+ Presence :: Unseen if splitted_slice. arity ( ) == 0 => {
1139
+ missing. push ( Slice ( Slice :: new ( None , FixedLen ( 0 ) ) ) )
1140
+ }
1141
+ Presence :: Unseen => { }
1142
+ }
1130
1143
}
1131
1144
}
1132
1145
ConstructorSet :: Unlistable => {
0 commit comments