@@ -148,8 +148,8 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
148
148
self . tables ,
149
149
) ;
150
150
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 ) ) ;
153
153
if !patcx. errors . is_empty ( ) {
154
154
patcx. report_inlining_errors ( arm. pat . span ) ;
155
155
have_errors = true ;
@@ -168,55 +168,57 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
168
168
169
169
// Then, if the match has no arms, check whether the scrutinee
170
170
// is uninhabited.
171
- let pat_ty = self . tables . node_type ( scrut. hir_id ) ;
171
+ let scrut_ty = self . tables . node_type ( scrut. hir_id ) ;
172
172
if inlined_arms. is_empty ( ) {
173
173
let scrutinee_is_visibly_uninhabited = if self . tcx . features ( ) . exhaustive_patterns {
174
174
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 )
176
176
} else {
177
- match pat_ty . kind {
177
+ match scrut_ty . kind {
178
178
ty:: Never => true ,
179
179
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 )
181
181
}
182
182
_ => false ,
183
183
}
184
184
} ;
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 {
186
192
// 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 ) ,
193
198
} ;
194
199
195
- if missing_variants. is_empty ( ) {
200
+ if non_empty_enum {
201
+ // Continue to the normal code path to display missing variants.
202
+ } else {
196
203
let mut err = create_e0004 (
197
204
self . tcx . sess ,
198
205
scrut. span ,
199
- format ! ( "non-exhaustive patterns: type `{}` is non-empty" , pat_ty ) ,
206
+ format ! ( "non-exhaustive patterns: type `{}` is non-empty" , scrut_ty ) ,
200
207
) ;
201
208
err. help (
202
209
"ensure that all possible cases are being handled, \
203
210
possibly by adding wildcards or more match arms",
204
211
) ;
205
212
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 ) ) ;
207
214
}
208
215
err. emit ( ) ;
209
216
return ;
210
- } else {
211
- // Continue to the normal code path
212
217
}
213
- } else {
214
- // If the type *is* uninhabited, it's vacuously exhaustive
215
- return ;
216
218
}
217
219
}
218
220
219
- let scrut_ty = self . tables . node_type ( scrut . hir_id ) ;
221
+ // Fifth, check if the match is exhaustive.
220
222
check_exhaustive ( cx, scrut_ty, scrut. span , & matrix, scrut. hir_id ) ;
221
223
} )
222
224
}
0 commit comments