@@ -166,60 +166,10 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
166166 // Fourth, check for unreachable arms.
167167 let matrix = check_arms ( cx, & inlined_arms, source) ;
168168
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-
221169 // 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) ;
223173 } )
224174 }
225175
@@ -483,7 +433,60 @@ fn check_exhaustive<'p, 'tcx>(
483433 sp : Span ,
484434 matrix : & Matrix < ' p , ' tcx > ,
485435 hir_id : HirId ,
436+ is_empty_match : bool ,
486437) {
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+
487490 let witnesses = match check_not_useful ( cx, scrut_ty, matrix, hir_id) {
488491 Ok ( _) => return ,
489492 Err ( err) => err,
0 commit comments