@@ -340,22 +340,27 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
340
340
pub fn from_pattern ( pat : & ' p Pat < ' tcx > ) -> Self {
341
341
PatStack ( smallvec ! [ pat] )
342
342
}
343
+
343
344
fn empty ( ) -> Self {
344
345
PatStack ( smallvec ! [ ] )
345
346
}
347
+
346
348
fn from_vec ( vec : SmallVec < [ & ' p Pat < ' tcx > ; 2 ] > ) -> Self {
347
349
PatStack ( vec)
348
350
}
351
+
349
352
fn from_slice ( s : & [ & ' p Pat < ' tcx > ] ) -> Self {
350
353
PatStack ( SmallVec :: from_slice ( s) )
351
354
}
352
355
353
356
fn is_empty ( & self ) -> bool {
354
357
self . 0 . is_empty ( )
355
358
}
359
+
356
360
fn len ( & self ) -> usize {
357
361
self . 0 . len ( )
358
362
}
363
+
359
364
fn head < ' a , ' p2 > ( & ' a self ) -> & ' p2 Pat < ' tcx >
360
365
where
361
366
' p : ' p2 ,
@@ -605,7 +610,7 @@ impl<'tcx> Constructor<'tcx> {
605
610
match self {
606
611
Wildcard => true ,
607
612
MissingConstructors ( _) => bug ! (
608
- "Not sure if MissingConstructors should be a wildcard. Shouldn 't happen anyways."
613
+ "not sure if MissingConstructors should be a wildcard; shouldn 't happen anyways."
609
614
) ,
610
615
_ => false ,
611
616
}
@@ -934,6 +939,32 @@ impl<'tcx> Constructor<'tcx> {
934
939
if used_ctors. iter ( ) . any ( overlaps) { smallvec ! [ ] } else { smallvec ! [ self ] }
935
940
}
936
941
VarLenSlice ( self_prefix, self_suffix) => {
942
+ // Assume we have the following match:
943
+ // ```
944
+ // match slice {
945
+ // [0] => {}
946
+ // [_, _, _] => {}
947
+ // [1, 2, 3, 4, 5, 6, ..] => {}
948
+ // [_, _, _, _, _, _, _, _] => {}
949
+ // [0, ..] => {}
950
+ // }
951
+ // ```
952
+ // We want to know which constructors are matched by the last pattern, but are not
953
+ // matched by the first four ones. Since we only speak of constructors here, we
954
+ // only care about the length of the slices and not the subpatterns.
955
+ // For that, we first notice that because of the third pattern, all constructors of
956
+ // lengths 6 or more are covered already. `max_len` will be `Some(6)`.
957
+ // Then we'll look at constructors of lengths < 6 to see which are missing. We can
958
+ // ignore pattern 4 because it's longer than 6. We are left with patterns 1 and 2.
959
+ // The `length` vector will therefore contain `[Start, Boundary(1), Boundary(3),
960
+ // Boundary(6)]`.
961
+ // The resulting list of remaining constructors will be those strictly between
962
+ // those boundaries. Knowing that `self_len` is 1, we get `[FixedLenSlice(2),
963
+ // FixedLenSlice(4), FixedLenSlice(5)]`.
964
+ // Notice that `FixedLenSlice(0)` is not covered by any of the patterns here, but
965
+ // we don't care because we only want constructors that _are_ matched by the last
966
+ // pattern.
967
+
937
968
// Initially we cover all slice lengths starting from self_len.
938
969
let self_len = self_prefix + self_suffix;
939
970
@@ -962,7 +993,7 @@ impl<'tcx> Constructor<'tcx> {
962
993
// of the lengths that will remain.
963
994
#[ derive( Clone , Copy , PartialEq , Eq , PartialOrd , Ord ) ]
964
995
enum Length {
965
- Start ,
996
+ Start , // `Start` will be sorted before `Boundary`
966
997
Boundary ( u64 ) ,
967
998
}
968
999
use Length :: * ;
@@ -1000,7 +1031,7 @@ impl<'tcx> Constructor<'tcx> {
1000
1031
1001
1032
// If there was a max_len, then we're done. Otherwise, we
1002
1033
// still need to include all lengths starting from the longest
1003
- // one til infinity, using VarLenSlice.
1034
+ // one until infinity, using VarLenSlice.
1004
1035
if max_len. is_none ( ) {
1005
1036
let final_length = match lengths. last ( ) . unwrap ( ) {
1006
1037
Start => self_len,
@@ -1137,13 +1168,15 @@ impl<'tcx> Constructor<'tcx> {
1137
1168
/// must have as many elements as this constructor's arity.
1138
1169
///
1139
1170
/// Examples:
1140
- /// self: Single
1141
- /// ty: tuple of 3 elements
1142
- /// pats: [10, 20, _] => (10, 20, _)
1171
+ /// `self`: `Constructor::Single`
1172
+ /// `ty`: `(u32, u32, u32)`
1173
+ /// `pats`: `[10, 20, _]`
1174
+ /// returns `(10, 20, _)`
1143
1175
///
1144
- /// self: Option::Some
1145
- /// ty: Option<bool>
1146
- /// pats: [false] => Some(false)
1176
+ /// `self`: `Constructor::Variant(Option::Some)`
1177
+ /// `ty`: `Option<bool>`
1178
+ /// `pats`: `[false]`
1179
+ /// returns `Some(false)`
1147
1180
fn apply < ' a > (
1148
1181
& self ,
1149
1182
cx : & MatchCheckCtxt < ' a , ' tcx > ,
@@ -1659,10 +1692,12 @@ impl<'tcx> fmt::Debug for MissingConstructors<'tcx> {
1659
1692
}
1660
1693
}
1661
1694
1662
- /// The implementation panics because this should not happen
1695
+ /// This is needed for the `PartialEq` impl of `Constructor`.
1696
+ /// Comparing a `Constructor::MissingConstructor` with something else
1697
+ /// should however never happen, so this implementaiton panics.
1663
1698
impl < ' tcx > PartialEq < Self > for MissingConstructors < ' tcx > {
1664
1699
fn eq ( & self , _other : & Self ) -> bool {
1665
- bug ! ( "Tried to compare MissingConstructors for equality" )
1700
+ bug ! ( "tried to compare MissingConstructors for equality" )
1666
1701
}
1667
1702
}
1668
1703
@@ -1982,18 +2017,13 @@ fn specialize_one_pattern<'p, 'a: 'p, 'p2: 'p, 'tcx>(
1982
2017
pat = subpattern;
1983
2018
}
1984
2019
1985
- if let MissingConstructors ( _) = constructor {
1986
- // By the invariant of MissingConstructors, we know that all non-wildcard constructors
1987
- // should be discarded.
1988
- return match * pat. kind {
1989
- PatKind :: Binding { .. } | PatKind :: Wild => smallvec ! [ PatStack :: empty( ) ] ,
1990
- _ => smallvec ! [ ] ,
1991
- } ;
1992
- } else if let Wildcard = constructor {
1993
- // If we get here, either there were only wildcards in the first component of the
1994
- // matrix, or we are in a special non_exhaustive case where we pretend the type has
1995
- // an extra `_` constructor to prevent exhaustive matching. In both cases, all
1996
- // non-wildcard constructors should be discarded.
2020
+ if let Wildcard | MissingConstructors ( _) = constructor {
2021
+ // If `constructor` is `Wildcard`: either there were only wildcards in the first component
2022
+ // of the matrix, or we are in a special non_exhaustive case where we pretend the type has
2023
+ // an extra `_` constructor to prevent exhaustive matching. In both cases, all non-wildcard
2024
+ // constructors should be discarded.
2025
+ // If `constructor` is `MissingConstructors(_)`: by the invariant of MissingConstructors,
2026
+ // we know that all non-wildcard constructors should be discarded.
1997
2027
return match * pat. kind {
1998
2028
PatKind :: Binding { .. } | PatKind :: Wild => smallvec ! [ PatStack :: empty( ) ] ,
1999
2029
_ => smallvec ! [ ] ,
0 commit comments