@@ -148,8 +148,8 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
148148 self . tables ,
149149 ) ;
150150 patcx. include_lint_checks ( ) ;
151- let pattern: & _ =
152- cx. pattern_arena . alloc ( expand_pattern ( cx, patcx . lower_pattern ( & arm . pat ) ) ) ;
151+ let pattern = patcx . lower_pattern ( & arm . pat ) ;
152+ let pattern : & _ = cx. pattern_arena . alloc ( expand_pattern ( cx, pattern ) ) ;
153153 if !patcx. errors . is_empty ( ) {
154154 patcx. report_inlining_errors ( arm. pat . span ) ;
155155 have_errors = true ;
@@ -168,55 +168,57 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
168168
169169 // Then, if the match has no arms, check whether the scrutinee
170170 // is uninhabited.
171- let pat_ty = self . tables . node_type ( scrut. hir_id ) ;
171+ let scrut_ty = self . tables . node_type ( scrut. hir_id ) ;
172172 if inlined_arms. is_empty ( ) {
173173 let scrutinee_is_visibly_uninhabited = if self . tcx . features ( ) . exhaustive_patterns {
174174 let module = self . tcx . hir ( ) . get_module_parent ( scrut. hir_id ) ;
175- self . tcx . is_ty_uninhabited_from ( module, pat_ty )
175+ self . tcx . is_ty_uninhabited_from ( module, scrut_ty )
176176 } else {
177- match pat_ty . kind {
177+ match scrut_ty . kind {
178178 ty:: Never => true ,
179179 ty:: Adt ( def, _) if def. is_enum ( ) => {
180- def. variants . is_empty ( ) && !cx. is_foreign_non_exhaustive_enum ( pat_ty )
180+ def. variants . is_empty ( ) && !cx. is_foreign_non_exhaustive_enum ( scrut_ty )
181181 }
182182 _ => false ,
183183 }
184184 } ;
185- if !scrutinee_is_visibly_uninhabited {
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 {
186192 // We know the type is inhabited, so this must be wrong
187- let ( def_span, missing_variants) = match pat_ty. kind {
188- ty:: Adt ( def, _) if def. is_enum ( ) => (
189- self . tcx . hir ( ) . span_if_local ( def. did ) ,
190- def. variants . iter ( ) . map ( |variant| variant. ident ) . collect ( ) ,
191- ) ,
192- _ => ( None , vec ! [ ] ) ,
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 ) ,
193198 } ;
194199
195- if missing_variants. is_empty ( ) {
200+ if non_empty_enum {
201+ // Continue to the normal code path to display missing variants.
202+ } else {
196203 let mut err = create_e0004 (
197204 self . tcx . sess ,
198205 scrut. span ,
199- format ! ( "non-exhaustive patterns: type `{}` is non-empty" , pat_ty ) ,
206+ format ! ( "non-exhaustive patterns: type `{}` is non-empty" , scrut_ty ) ,
200207 ) ;
201208 err. help (
202209 "ensure that all possible cases are being handled, \
203210 possibly by adding wildcards or more match arms",
204211 ) ;
205212 if let Some ( sp) = def_span {
206- err. span_label ( sp, format ! ( "`{}` defined here" , pat_ty ) ) ;
213+ err. span_label ( sp, format ! ( "`{}` defined here" , scrut_ty ) ) ;
207214 }
208215 err. emit ( ) ;
209216 return ;
210- } else {
211- // Continue to the normal code path
212217 }
213- } else {
214- // If the type *is* uninhabited, it's vacuously exhaustive
215- return ;
216218 }
217219 }
218220
219- let scrut_ty = self . tables . node_type ( scrut . hir_id ) ;
221+ // Fifth, check if the match is exhaustive.
220222 check_exhaustive ( cx, scrut_ty, scrut. span , & matrix, scrut. hir_id ) ;
221223 } )
222224 }
0 commit comments