Skip to content

Commit bfb556f

Browse files
committed
Move empty_match check after usefulness check
1 parent 3e6dc2b commit bfb556f

File tree

2 files changed

+39
-41
lines changed

2 files changed

+39
-41
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,8 @@ impl<'tcx> Witness<'tcx> {
12201220
///
12211221
/// We make sure to omit constructors that are statically impossible. E.g., for
12221222
/// `Option<!>`, we do not include `Some(_)` in the returned list of constructors.
1223+
/// Invariant: this returns an empty `Vec` if and only if the type is uninhabited (as determined by
1224+
/// `cx.is_uninhabited()`).
12231225
fn all_constructors<'a, 'tcx>(
12241226
cx: &mut MatchCheckCtxt<'a, 'tcx>,
12251227
pcx: PatCtxt<'tcx>,

src/librustc_mir/hair/pattern/check_match.rs

Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -438,56 +438,52 @@ fn check_exhaustive<'p, 'tcx>(
438438
// If the match has no arms, check whether the scrutinee is uninhabited.
439439
// Note: An empty match isn't the same as an empty matrix for diagnostics purposes, since an
440440
// 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 non_empty_enum = match scrut_ty.kind {
463-
ty::Adt(def, _) => def.is_enum() && !def.variants.is_empty(),
464-
_ => false,
465-
};
466-
467-
if non_empty_enum {
468-
// Continue to the normal code path to display missing variants.
469-
} else {
470-
let mut err = create_e0004(
471-
cx.tcx.sess,
472-
sp,
473-
format!("non-exhaustive patterns: type `{}` is non-empty", scrut_ty),
474-
);
475-
err.help(
476-
"ensure that all possible cases are being handled, \
477-
possibly by adding wildcards or more match arms",
478-
);
479-
adt_defined_here(cx, &mut err, scrut_ty, &[]);
480-
err.emit();
481-
return;
441+
let scrutinee_is_visibly_uninhabited = if cx.tcx.features().exhaustive_patterns {
442+
let module = cx.tcx.hir().get_module_parent(hir_id);
443+
cx.tcx.is_ty_uninhabited_from(module, scrut_ty)
444+
} else {
445+
match scrut_ty.kind {
446+
ty::Never => true,
447+
ty::Adt(def, _) if def.is_enum() => {
448+
def.variants.is_empty() && !cx.is_foreign_non_exhaustive_enum(scrut_ty)
482449
}
450+
_ => false,
483451
}
452+
};
453+
if is_empty_match && scrutinee_is_visibly_uninhabited {
454+
// If the type *is* uninhabited, it's vacuously exhaustive.
455+
// This early return is only needed here because in the absence of the
456+
// `exhaustive_patterns` feature, empty matches are not detected by `is_useful`
457+
// to exhaustively match uninhabited types.
458+
return;
484459
}
485460

486461
let witnesses = match check_not_useful(cx, scrut_ty, matrix, hir_id) {
487462
Ok(_) => return,
488463
Err(err) => err,
489464
};
490465

466+
let non_empty_enum = match scrut_ty.kind {
467+
ty::Adt(def, _) => def.is_enum() && !def.variants.is_empty(),
468+
_ => false,
469+
};
470+
// In the case of an empty match, replace the '`_` not covered' diagnostic with something more
471+
// informative.
472+
if is_empty_match && !non_empty_enum {
473+
let mut err = create_e0004(
474+
cx.tcx.sess,
475+
sp,
476+
format!("non-exhaustive patterns: type `{}` is non-empty", scrut_ty),
477+
);
478+
err.help(
479+
"ensure that all possible cases are being handled, \
480+
possibly by adding wildcards or more match arms",
481+
);
482+
adt_defined_here(cx, &mut err, scrut_ty, &[]);
483+
err.emit();
484+
return;
485+
}
486+
491487
let joined_patterns = joined_uncovered_patterns(&witnesses);
492488
let mut err = create_e0004(
493489
cx.tcx.sess,

0 commit comments

Comments
 (0)