@@ -16,8 +16,8 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
16
16
use rustc_middle:: ty:: { self , AdtDef , Ty , TyCtxt } ;
17
17
use rustc_pattern_analysis:: errors:: Uncovered ;
18
18
use rustc_pattern_analysis:: rustc:: {
19
- Constructor , DeconstructedPat , MatchArm , RustcPatCtxt as PatCtxt , Usefulness , UsefulnessReport ,
20
- WitnessPat ,
19
+ Constructor , DeconstructedPat , MatchArm , RevealedTy , RustcPatCtxt as PatCtxt , Usefulness ,
20
+ UsefulnessReport , WitnessPat ,
21
21
} ;
22
22
use rustc_session:: lint:: builtin:: {
23
23
BINDINGS_WITH_VARIANT_NAME , IRREFUTABLE_LET_PATTERNS , UNREACHABLE_PATTERNS ,
@@ -998,27 +998,31 @@ fn report_non_exhaustive_match<'p, 'tcx>(
998
998
err. note ( format ! ( "the matched value is of type `{}`" , scrut_ty) ) ;
999
999
1000
1000
if !is_empty_match {
1001
- let mut non_exhaustive_tys = FxIndexSet :: default ( ) ;
1001
+ let mut special_tys = FxIndexSet :: default ( ) ;
1002
1002
// Look at the first witness.
1003
- collect_non_exhaustive_tys ( cx, & witnesses[ 0 ] , & mut non_exhaustive_tys ) ;
1003
+ collect_special_tys ( cx, & witnesses[ 0 ] , & mut special_tys ) ;
1004
1004
1005
- for ty in non_exhaustive_tys {
1005
+ for ty in special_tys {
1006
1006
if ty. is_ptr_sized_integral ( ) {
1007
- if ty == cx. tcx . types . usize {
1007
+ if ty. inner ( ) == cx. tcx . types . usize {
1008
1008
err. note ( format ! (
1009
1009
"`{ty}` does not have a fixed maximum value, so half-open ranges are necessary to match \
1010
1010
exhaustively",
1011
1011
) ) ;
1012
- } else if ty == cx. tcx . types . isize {
1012
+ } else if ty. inner ( ) == cx. tcx . types . isize {
1013
1013
err. note ( format ! (
1014
1014
"`{ty}` does not have fixed minimum and maximum values, so half-open ranges are necessary to match \
1015
1015
exhaustively",
1016
1016
) ) ;
1017
1017
}
1018
- } else if ty == cx. tcx . types . str_ {
1018
+ } else if ty. inner ( ) == cx. tcx . types . str_ {
1019
1019
err. note ( "`&str` cannot be matched exhaustively, so a wildcard `_` is necessary" ) ;
1020
- } else if cx. is_foreign_non_exhaustive_enum ( cx . reveal_opaque_ty ( ty ) ) {
1020
+ } else if cx. is_foreign_non_exhaustive_enum ( ty ) {
1021
1021
err. note ( format ! ( "`{ty}` is marked as non-exhaustive, so a wildcard `_` is necessary to match exhaustively" ) ) ;
1022
+ } else if cx. is_uninhabited ( ty. inner ( ) ) && cx. tcx . features ( ) . min_exhaustive_patterns {
1023
+ // The type is uninhabited yet there is a witness: we must be in the `MaybeInvalid`
1024
+ // case.
1025
+ err. note ( format ! ( "`{ty}` is uninhabited but is not being matched by value, so a wildcard `_` is required" ) ) ;
1022
1026
}
1023
1027
}
1024
1028
}
@@ -1168,22 +1172,22 @@ fn joined_uncovered_patterns<'p, 'tcx>(
1168
1172
}
1169
1173
}
1170
1174
1171
- fn collect_non_exhaustive_tys < ' tcx > (
1175
+ /// Collect types that require specific explanations when they show up in witnesses.
1176
+ fn collect_special_tys < ' tcx > (
1172
1177
cx : & PatCtxt < ' _ , ' tcx > ,
1173
1178
pat : & WitnessPat < ' _ , ' tcx > ,
1174
- non_exhaustive_tys : & mut FxIndexSet < Ty < ' tcx > > ,
1179
+ special_tys : & mut FxIndexSet < RevealedTy < ' tcx > > ,
1175
1180
) {
1176
- if matches ! ( pat. ctor( ) , Constructor :: NonExhaustive ) {
1177
- non_exhaustive_tys . insert ( pat. ty ( ) . inner ( ) ) ;
1181
+ if matches ! ( pat. ctor( ) , Constructor :: NonExhaustive | Constructor :: Never ) {
1182
+ special_tys . insert ( * pat. ty ( ) ) ;
1178
1183
}
1179
1184
if let Constructor :: IntRange ( range) = pat. ctor ( ) {
1180
1185
if cx. is_range_beyond_boundaries ( range, * pat. ty ( ) ) {
1181
1186
// The range denotes the values before `isize::MIN` or the values after `usize::MAX`/`isize::MAX`.
1182
- non_exhaustive_tys . insert ( pat. ty ( ) . inner ( ) ) ;
1187
+ special_tys . insert ( * pat. ty ( ) ) ;
1183
1188
}
1184
1189
}
1185
- pat. iter_fields ( )
1186
- . for_each ( |field_pat| collect_non_exhaustive_tys ( cx, field_pat, non_exhaustive_tys) )
1190
+ pat. iter_fields ( ) . for_each ( |field_pat| collect_special_tys ( cx, field_pat, special_tys) )
1187
1191
}
1188
1192
1189
1193
fn report_adt_defined_here < ' tcx > (
0 commit comments