@@ -606,8 +606,9 @@ pub(super) enum Constructor<'tcx> {
606606 /// for those types for which we cannot list constructors explicitly, like `f64` and `str`.
607607 NonExhaustive ,
608608 /// 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 } ,
611612 /// Wildcard pattern.
612613 Wildcard ,
613614}
@@ -617,6 +618,10 @@ impl<'tcx> Constructor<'tcx> {
617618 matches ! ( self , Wildcard )
618619 }
619620
621+ pub ( super ) fn is_non_exhaustive ( & self ) -> bool {
622+ matches ! ( self , NonExhaustive )
623+ }
624+
620625 fn as_int_range ( & self ) -> Option < & IntRange > {
621626 match self {
622627 IntRange ( range) => Some ( range) ,
@@ -756,7 +761,7 @@ impl<'tcx> Constructor<'tcx> {
756761 // Wildcards cover anything
757762 ( _, Wildcard ) => true ,
758763 // The missing ctors are not covered by anything in the matrix except wildcards.
759- ( Missing | Wildcard , _) => false ,
764+ ( Missing { .. } | Wildcard , _) => false ,
760765
761766 ( Single , Single ) => true ,
762767 ( Variant ( self_id) , Variant ( other_id) ) => self_id == other_id,
@@ -829,7 +834,7 @@ impl<'tcx> Constructor<'tcx> {
829834 . any ( |other| slice. is_covered_by ( other) ) ,
830835 // This constructor is never covered by anything else
831836 NonExhaustive => false ,
832- Str ( ..) | FloatRange ( ..) | Opaque | Missing | Wildcard => {
837+ Str ( ..) | FloatRange ( ..) | Opaque | Missing { .. } | Wildcard => {
833838 span_bug ! ( pcx. span, "found unexpected ctor in all_ctors: {:?}" , self )
834839 }
835840 }
@@ -919,8 +924,14 @@ impl<'tcx> SplitWildcard<'tcx> {
919924 && !cx. tcx . features ( ) . exhaustive_patterns
920925 && !pcx. is_top_level ;
921926
922- if is_secretly_empty || is_declared_nonexhaustive {
927+ if is_secretly_empty {
923928 smallvec ! [ NonExhaustive ]
929+ } else if is_declared_nonexhaustive {
930+ def. variants
931+ . indices ( )
932+ . map ( |idx| Variant ( idx) )
933+ . chain ( Some ( NonExhaustive ) )
934+ . collect ( )
924935 } else if cx. tcx . features ( ) . exhaustive_patterns {
925936 // If `exhaustive_patterns` is enabled, we exclude variants known to be
926937 // uninhabited.
@@ -975,6 +986,7 @@ impl<'tcx> SplitWildcard<'tcx> {
975986 // This type is one for which we cannot list constructors, like `str` or `f64`.
976987 _ => smallvec ! [ NonExhaustive ] ,
977988 } ;
989+
978990 SplitWildcard { matrix_ctors : Vec :: new ( ) , all_ctors }
979991 }
980992
@@ -1039,7 +1051,17 @@ impl<'tcx> SplitWildcard<'tcx> {
10391051 // sometimes prefer reporting the list of constructors instead of just `_`.
10401052 let report_when_all_missing = pcx. is_top_level && !IntRange :: is_integral ( pcx. ty ) ;
10411053 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+ }
10431065 } else {
10441066 Wildcard
10451067 } ;
@@ -1176,7 +1198,12 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
11761198 }
11771199 _ => bug ! ( "bad slice pattern {:?} {:?}" , constructor, ty) ,
11781200 } ,
1179- Str ( ..) | FloatRange ( ..) | IntRange ( ..) | NonExhaustive | Opaque | Missing
1201+ Str ( ..)
1202+ | FloatRange ( ..)
1203+ | IntRange ( ..)
1204+ | NonExhaustive
1205+ | Opaque
1206+ | Missing { .. }
11801207 | Wildcard => Fields :: Slice ( & [ ] ) ,
11811208 } ;
11821209 debug ! ( "Fields::wildcards({:?}, {:?}) = {:#?}" , constructor, ty, ret) ;
@@ -1189,15 +1216,18 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
11891216 /// This is roughly the inverse of `specialize_constructor`.
11901217 ///
11911218 /// 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, _]`
11951224 /// returns `Foo(10, 20, _)`
11961225 ///
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]`
12001229 /// returns `Some(false)`
1230+ /// ```
12011231 pub ( super ) fn apply ( self , pcx : PatCtxt < ' _ , ' p , ' tcx > , ctor : & Constructor < ' tcx > ) -> Pat < ' tcx > {
12021232 let subpatterns_and_indices = self . patterns_and_indices ( ) ;
12031233 let mut subpatterns = subpatterns_and_indices. iter ( ) . map ( |& ( _, p) | p) . cloned ( ) ;
@@ -1265,7 +1295,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
12651295 NonExhaustive => PatKind :: Wild ,
12661296 Wildcard => return Pat :: wildcard_from_ty ( pcx. ty ) ,
12671297 Opaque => bug ! ( "we should not try to apply an opaque constructor" ) ,
1268- Missing => bug ! (
1298+ Missing { .. } => bug ! (
12691299 "trying to apply the `Missing` constructor; this should have been done in `apply_constructors`"
12701300 ) ,
12711301 } ;
0 commit comments