@@ -16,8 +16,8 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
1616use rustc_middle:: ty:: { self , AdtDef , Ty , TyCtxt } ;
1717use rustc_pattern_analysis:: errors:: Uncovered ;
1818use 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 ,
2121} ;
2222use rustc_session:: lint:: builtin:: {
2323 BINDINGS_WITH_VARIANT_NAME , IRREFUTABLE_LET_PATTERNS , UNREACHABLE_PATTERNS ,
@@ -998,27 +998,31 @@ fn report_non_exhaustive_match<'p, 'tcx>(
998998 err. note ( format ! ( "the matched value is of type `{}`" , scrut_ty) ) ;
999999
10001000 if !is_empty_match {
1001- let mut non_exhaustive_tys = FxIndexSet :: default ( ) ;
1001+ let mut special_tys = FxIndexSet :: default ( ) ;
10021002 // 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 ) ;
10041004
1005- for ty in non_exhaustive_tys {
1005+ for ty in special_tys {
10061006 if ty. is_ptr_sized_integral ( ) {
1007- if ty == cx. tcx . types . usize {
1007+ if ty. inner ( ) == cx. tcx . types . usize {
10081008 err. note ( format ! (
10091009 "`{ty}` does not have a fixed maximum value, so half-open ranges are necessary to match \
10101010 exhaustively",
10111011 ) ) ;
1012- } else if ty == cx. tcx . types . isize {
1012+ } else if ty. inner ( ) == cx. tcx . types . isize {
10131013 err. note ( format ! (
10141014 "`{ty}` does not have fixed minimum and maximum values, so half-open ranges are necessary to match \
10151015 exhaustively",
10161016 ) ) ;
10171017 }
1018- } else if ty == cx. tcx . types . str_ {
1018+ } else if ty. inner ( ) == cx. tcx . types . str_ {
10191019 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 ) {
10211021 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" ) ) ;
10221026 }
10231027 }
10241028 }
@@ -1168,22 +1172,22 @@ fn joined_uncovered_patterns<'p, 'tcx>(
11681172 }
11691173}
11701174
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 > (
11721177 cx : & PatCtxt < ' _ , ' tcx > ,
11731178 pat : & WitnessPat < ' _ , ' tcx > ,
1174- non_exhaustive_tys : & mut FxIndexSet < Ty < ' tcx > > ,
1179+ special_tys : & mut FxIndexSet < RevealedTy < ' tcx > > ,
11751180) {
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 ( ) ) ;
11781183 }
11791184 if let Constructor :: IntRange ( range) = pat. ctor ( ) {
11801185 if cx. is_range_beyond_boundaries ( range, * pat. ty ( ) ) {
11811186 // 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 ( ) ) ;
11831188 }
11841189 }
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) )
11871191}
11881192
11891193fn report_adt_defined_here < ' tcx > (
0 commit comments