@@ -606,8 +606,9 @@ pub(super) enum Constructor<'tcx> {
606
606
/// for those types for which we cannot list constructors explicitly, like `f64` and `str`.
607
607
NonExhaustive ,
608
608
/// Stands for constructors that are not seen in the matrix, as explained in the documentation
609
- /// for [`SplitWildcard`].
610
- Missing ,
609
+ /// for [`SplitWildcard`]. The carried `bool` is used for the `non_exhaustive_omitted_patterns`
610
+ /// lint.
611
+ Missing { nonexhaustive_enum_missing_real_variants : bool } ,
611
612
/// Wildcard pattern.
612
613
Wildcard ,
613
614
}
@@ -617,6 +618,10 @@ impl<'tcx> Constructor<'tcx> {
617
618
matches ! ( self , Wildcard )
618
619
}
619
620
621
+ pub ( super ) fn is_non_exhaustive ( & self ) -> bool {
622
+ matches ! ( self , NonExhaustive )
623
+ }
624
+
620
625
fn as_int_range ( & self ) -> Option < & IntRange > {
621
626
match self {
622
627
IntRange ( range) => Some ( range) ,
@@ -756,7 +761,7 @@ impl<'tcx> Constructor<'tcx> {
756
761
// Wildcards cover anything
757
762
( _, Wildcard ) => true ,
758
763
// The missing ctors are not covered by anything in the matrix except wildcards.
759
- ( Missing | Wildcard , _) => false ,
764
+ ( Missing { .. } | Wildcard , _) => false ,
760
765
761
766
( Single , Single ) => true ,
762
767
( Variant ( self_id) , Variant ( other_id) ) => self_id == other_id,
@@ -829,7 +834,7 @@ impl<'tcx> Constructor<'tcx> {
829
834
. any ( |other| slice. is_covered_by ( other) ) ,
830
835
// This constructor is never covered by anything else
831
836
NonExhaustive => false ,
832
- Str ( ..) | FloatRange ( ..) | Opaque | Missing | Wildcard => {
837
+ Str ( ..) | FloatRange ( ..) | Opaque | Missing { .. } | Wildcard => {
833
838
span_bug ! ( pcx. span, "found unexpected ctor in all_ctors: {:?}" , self )
834
839
}
835
840
}
@@ -919,8 +924,14 @@ impl<'tcx> SplitWildcard<'tcx> {
919
924
&& !cx. tcx . features ( ) . exhaustive_patterns
920
925
&& !pcx. is_top_level ;
921
926
922
- if is_secretly_empty || is_declared_nonexhaustive {
927
+ if is_secretly_empty {
923
928
smallvec ! [ NonExhaustive ]
929
+ } else if is_declared_nonexhaustive {
930
+ def. variants
931
+ . indices ( )
932
+ . map ( |idx| Variant ( idx) )
933
+ . chain ( Some ( NonExhaustive ) )
934
+ . collect ( )
924
935
} else if cx. tcx . features ( ) . exhaustive_patterns {
925
936
// If `exhaustive_patterns` is enabled, we exclude variants known to be
926
937
// uninhabited.
@@ -975,6 +986,7 @@ impl<'tcx> SplitWildcard<'tcx> {
975
986
// This type is one for which we cannot list constructors, like `str` or `f64`.
976
987
_ => smallvec ! [ NonExhaustive ] ,
977
988
} ;
989
+
978
990
SplitWildcard { matrix_ctors : Vec :: new ( ) , all_ctors }
979
991
}
980
992
@@ -1039,7 +1051,17 @@ impl<'tcx> SplitWildcard<'tcx> {
1039
1051
// sometimes prefer reporting the list of constructors instead of just `_`.
1040
1052
let report_when_all_missing = pcx. is_top_level && !IntRange :: is_integral ( pcx. ty ) ;
1041
1053
let ctor = if !self . matrix_ctors . is_empty ( ) || report_when_all_missing {
1042
- Missing
1054
+ if pcx. is_non_exhaustive {
1055
+ Missing {
1056
+ nonexhaustive_enum_missing_real_variants : self
1057
+ . iter_missing ( pcx)
1058
+ . filter ( |c| !c. is_non_exhaustive ( ) )
1059
+ . next ( )
1060
+ . is_some ( ) ,
1061
+ }
1062
+ } else {
1063
+ Missing { nonexhaustive_enum_missing_real_variants : false }
1064
+ }
1043
1065
} else {
1044
1066
Wildcard
1045
1067
} ;
@@ -1176,7 +1198,12 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
1176
1198
}
1177
1199
_ => bug ! ( "bad slice pattern {:?} {:?}" , constructor, ty) ,
1178
1200
} ,
1179
- Str ( ..) | FloatRange ( ..) | IntRange ( ..) | NonExhaustive | Opaque | Missing
1201
+ Str ( ..)
1202
+ | FloatRange ( ..)
1203
+ | IntRange ( ..)
1204
+ | NonExhaustive
1205
+ | Opaque
1206
+ | Missing { .. }
1180
1207
| Wildcard => Fields :: Slice ( & [ ] ) ,
1181
1208
} ;
1182
1209
debug ! ( "Fields::wildcards({:?}, {:?}) = {:#?}" , constructor, ty, ret) ;
@@ -1189,15 +1216,18 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
1189
1216
/// This is roughly the inverse of `specialize_constructor`.
1190
1217
///
1191
1218
/// Examples:
1192
- /// `ctor`: `Constructor::Single`
1193
- /// `ty`: `Foo(u32, u32, u32)`
1194
- /// `self`: `[10, 20, _]`
1219
+ ///
1220
+ /// ```text
1221
+ /// ctor: `Constructor::Single`
1222
+ /// ty: `Foo(u32, u32, u32)`
1223
+ /// self: `[10, 20, _]`
1195
1224
/// returns `Foo(10, 20, _)`
1196
1225
///
1197
- /// ` ctor` : `Constructor::Variant(Option::Some)`
1198
- /// `ty` : `Option<bool>`
1199
- /// ` self` : `[false]`
1226
+ /// ctor: `Constructor::Variant(Option::Some)`
1227
+ /// ty : `Option<bool>`
1228
+ /// self: `[false]`
1200
1229
/// returns `Some(false)`
1230
+ /// ```
1201
1231
pub ( super ) fn apply ( self , pcx : PatCtxt < ' _ , ' p , ' tcx > , ctor : & Constructor < ' tcx > ) -> Pat < ' tcx > {
1202
1232
let subpatterns_and_indices = self . patterns_and_indices ( ) ;
1203
1233
let mut subpatterns = subpatterns_and_indices. iter ( ) . map ( |& ( _, p) | p) . cloned ( ) ;
@@ -1265,7 +1295,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
1265
1295
NonExhaustive => PatKind :: Wild ,
1266
1296
Wildcard => return Pat :: wildcard_from_ty ( pcx. ty ) ,
1267
1297
Opaque => bug ! ( "we should not try to apply an opaque constructor" ) ,
1268
- Missing => bug ! (
1298
+ Missing { .. } => bug ! (
1269
1299
"trying to apply the `Missing` constructor; this should have been done in `apply_constructors`"
1270
1300
) ,
1271
1301
} ;
0 commit comments