1
Fork 0

Rollup merge of #111624 - cjgillot:private-uninhabited-pattern, r=petrochenkov

Emit diagnostic for privately uninhabited uncovered witnesses.

Fixes https://github.com/rust-lang/rust/issues/104034

cc `@Nadrieril`
This commit is contained in:
Matthias Krüger 2023-05-25 08:01:08 +02:00 committed by GitHub
commit 725cadb276
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 33 additions and 1 deletions

View file

@ -781,6 +781,8 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> {
pub interpreted_as_const: Option<InterpretedAsConst>,
#[subdiagnostic]
pub adt_defined_here: Option<AdtDefinedHere<'tcx>>,
#[note(mir_build_privately_uninhabited)]
pub witness_1_is_privately_uninhabited: Option<()>,
#[note(mir_build_pattern_ty)]
pub _p: (),
pub pattern_ty: Ty<'tcx>,

View file

@ -479,12 +479,30 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
AdtDefinedHere { adt_def_span, ty, variants }
};
// Emit an extra note if the first uncovered witness is
// visibly uninhabited anywhere in the current crate.
let witness_1_is_privately_uninhabited =
if cx.tcx.features().exhaustive_patterns
&& let Some(witness_1) = witnesses.get(0)
&& let ty::Adt(adt, substs) = witness_1.ty().kind()
&& adt.is_enum()
&& let Constructor::Variant(variant_index) = witness_1.ctor()
{
let variant = adt.variant(*variant_index);
let inhabited = variant.inhabited_predicate(cx.tcx, *adt).subst(cx.tcx, substs);
assert!(inhabited.apply(cx.tcx, cx.param_env, cx.module));
!inhabited.apply_ignore_module(cx.tcx, cx.param_env)
} else {
false
};
self.error = Err(self.tcx.sess.emit_err(PatternNotCovered {
span: pat.span,
origin,
uncovered: Uncovered::new(pat.span, &cx, witnesses),
inform,
interpreted_as_const,
witness_1_is_privately_uninhabited: witness_1_is_privately_uninhabited.then_some(()),
_p: (),
pattern_ty,
let_suggestion,