@@ -166,60 +166,10 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
166
166
// Fourth, check for unreachable arms.
167
167
let matrix = check_arms ( cx, & inlined_arms, source) ;
168
168
169
- // Then, if the match has no arms, check whether the scrutinee
170
- // is uninhabited.
171
- let scrut_ty = self . tables . node_type ( scrut. hir_id ) ;
172
- if inlined_arms. is_empty ( ) {
173
- let scrutinee_is_visibly_uninhabited = if self . tcx . features ( ) . exhaustive_patterns {
174
- let module = self . tcx . hir ( ) . get_module_parent ( scrut. hir_id ) ;
175
- self . tcx . is_ty_uninhabited_from ( module, scrut_ty)
176
- } else {
177
- match scrut_ty. kind {
178
- ty:: Never => true ,
179
- ty:: Adt ( def, _) if def. is_enum ( ) => {
180
- def. variants . is_empty ( ) && !cx. is_foreign_non_exhaustive_enum ( scrut_ty)
181
- }
182
- _ => false ,
183
- }
184
- } ;
185
- if scrutinee_is_visibly_uninhabited {
186
- // If the type *is* uninhabited, it's vacuously exhaustive.
187
- // This early return is only needed here because in the absence of the
188
- // `exhaustive_patterns` feature, empty matches are not detected by `is_useful`
189
- // to exhaustively match uninhabited types.
190
- return ;
191
- } else {
192
- // We know the type is inhabited, so this must be wrong
193
- let ( def_span, non_empty_enum) = match scrut_ty. kind {
194
- ty:: Adt ( def, _) if def. is_enum ( ) => {
195
- ( self . tcx . hir ( ) . span_if_local ( def. did ) , !def. variants . is_empty ( ) )
196
- }
197
- _ => ( None , false ) ,
198
- } ;
199
-
200
- if non_empty_enum {
201
- // Continue to the normal code path to display missing variants.
202
- } else {
203
- let mut err = create_e0004 (
204
- self . tcx . sess ,
205
- scrut. span ,
206
- format ! ( "non-exhaustive patterns: type `{}` is non-empty" , scrut_ty) ,
207
- ) ;
208
- err. help (
209
- "ensure that all possible cases are being handled, \
210
- possibly by adding wildcards or more match arms",
211
- ) ;
212
- if let Some ( sp) = def_span {
213
- err. span_label ( sp, format ! ( "`{}` defined here" , scrut_ty) ) ;
214
- }
215
- err. emit ( ) ;
216
- return ;
217
- }
218
- }
219
- }
220
-
221
169
// Fifth, check if the match is exhaustive.
222
- check_exhaustive ( cx, scrut_ty, scrut. span , & matrix, scrut. hir_id ) ;
170
+ let scrut_ty = self . tables . node_type ( scrut. hir_id ) ;
171
+ let is_empty_match = inlined_arms. is_empty ( ) ;
172
+ check_exhaustive ( cx, scrut_ty, scrut. span , & matrix, scrut. hir_id , is_empty_match) ;
223
173
} )
224
174
}
225
175
@@ -483,7 +433,60 @@ fn check_exhaustive<'p, 'tcx>(
483
433
sp : Span ,
484
434
matrix : & Matrix < ' p , ' tcx > ,
485
435
hir_id : HirId ,
436
+ is_empty_match : bool ,
486
437
) {
438
+ // If the match has no arms, check whether the scrutinee is uninhabited.
439
+ // Note: An empty match isn't the same as an empty matrix for diagnostics purposes, since an
440
+ // empty matrix can occur when there are arms, if those arms all have guards.
441
+ if is_empty_match {
442
+ let scrutinee_is_visibly_uninhabited = if cx. tcx . features ( ) . exhaustive_patterns {
443
+ let module = cx. tcx . hir ( ) . get_module_parent ( hir_id) ;
444
+ cx. tcx . is_ty_uninhabited_from ( module, scrut_ty)
445
+ } else {
446
+ match scrut_ty. kind {
447
+ ty:: Never => true ,
448
+ ty:: Adt ( def, _) if def. is_enum ( ) => {
449
+ def. variants . is_empty ( ) && !cx. is_foreign_non_exhaustive_enum ( scrut_ty)
450
+ }
451
+ _ => false ,
452
+ }
453
+ } ;
454
+ if scrutinee_is_visibly_uninhabited {
455
+ // If the type *is* uninhabited, it's vacuously exhaustive.
456
+ // This early return is only needed here because in the absence of the
457
+ // `exhaustive_patterns` feature, empty matches are not detected by `is_useful`
458
+ // to exhaustively match uninhabited types.
459
+ return ;
460
+ } else {
461
+ // We know the type is inhabited, so this must be wrong
462
+ let ( def_span, non_empty_enum) = match scrut_ty. kind {
463
+ ty:: Adt ( def, _) if def. is_enum ( ) => {
464
+ ( cx. tcx . hir ( ) . span_if_local ( def. did ) , !def. variants . is_empty ( ) )
465
+ }
466
+ _ => ( None , false ) ,
467
+ } ;
468
+
469
+ if non_empty_enum {
470
+ // Continue to the normal code path to display missing variants.
471
+ } else {
472
+ let mut err = create_e0004 (
473
+ cx. tcx . sess ,
474
+ sp,
475
+ format ! ( "non-exhaustive patterns: type `{}` is non-empty" , scrut_ty) ,
476
+ ) ;
477
+ err. help (
478
+ "ensure that all possible cases are being handled, \
479
+ possibly by adding wildcards or more match arms",
480
+ ) ;
481
+ if let Some ( sp) = def_span {
482
+ err. span_label ( sp, format ! ( "`{}` defined here" , scrut_ty) ) ;
483
+ }
484
+ err. emit ( ) ;
485
+ return ;
486
+ }
487
+ }
488
+ }
489
+
487
490
let witnesses = match check_not_useful ( cx, scrut_ty, matrix, hir_id) {
488
491
Ok ( _) => return ,
489
492
Err ( err) => err,
0 commit comments