@@ -859,6 +859,7 @@ impl<'tcx> Constructor<'tcx> {
859859}
860860
861861/// Describes the set of all constructors for a type.
862+ #[ derive( Debug ) ]
862863pub ( super ) enum ConstructorSet {
863864 /// The type has a single constructor, e.g. `&T` or a struct.
864865 Single ,
@@ -903,6 +904,7 @@ pub(super) enum ConstructorSet {
903904/// - constructors in `present` and `missing` are split for the column; in other words, they are
904905/// either fully included in or disjoint from each constructor in the column. This avoids
905906/// non-trivial intersections like between `0..10` and `5..15`.
907+ #[ derive( Debug ) ]
906908struct SplitConstructorSet < ' tcx > {
907909 present : SmallVec < [ Constructor < ' tcx > ; 1 ] > ,
908910 missing : Vec < Constructor < ' tcx > > ,
@@ -911,8 +913,8 @@ struct SplitConstructorSet<'tcx> {
911913}
912914
913915impl ConstructorSet {
916+ #[ instrument( level = "debug" , skip( cx) , ret) ]
914917 pub ( super ) fn for_ty < ' p , ' tcx > ( cx : & MatchCheckCtxt < ' p , ' tcx > , ty : Ty < ' tcx > ) -> Self {
915- debug ! ( "ConstructorSet::for_ty({:?})" , ty) ;
916918 let make_range =
917919 |start, end| IntRange :: from_range ( cx. tcx , start, end, ty, RangeEnd :: Included ) ;
918920 // This determines the set of all possible constructors for the type `ty`. For numbers,
@@ -1036,6 +1038,7 @@ impl ConstructorSet {
10361038 /// This is the core logical operation of exhaustiveness checking. This analyzes a column a
10371039 /// constructors to 1/ determine which constructors of the type (if any) are missing; 2/ split
10381040 /// constructors to handle non-trivial intersections e.g. on ranges or slices.
1041+ #[ instrument( level = "debug" , skip( self , pcx, ctors) , ret) ]
10391042 fn split < ' a , ' tcx > (
10401043 & self ,
10411044 pcx : & PatCtxt < ' _ , ' _ , ' tcx > ,
@@ -1111,7 +1114,7 @@ impl ConstructorSet {
11111114 }
11121115 & ConstructorSet :: Slice ( array_len) => {
11131116 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 ) ) ;
11151118 for ( seen, splitted_slice) in base_slice. split ( seen_slices) {
11161119 let ctor = Slice ( splitted_slice) ;
11171120 match seen {
@@ -1121,12 +1124,22 @@ impl ConstructorSet {
11211124 }
11221125 }
11231126 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+ }
11301143 }
11311144 }
11321145 ConstructorSet :: Unlistable => {
0 commit comments