diff options
| author | Camille GILLOT <gillot.camille@gmail.com> | 2023-04-09 08:09:43 +0000 |
|---|---|---|
| committer | Camille GILLOT <gillot.camille@gmail.com> | 2023-05-24 19:16:07 +0000 |
| commit | 9a7ed3625f57ad21d646f835975ab42929214b60 (patch) | |
| tree | 20e1e872db704783d3dd27a92eb15b51efb08abf /compiler/rustc_mir_build/src | |
| parent | b3cbf7c8351dd48dc2e07a1cdc69620f8e40dd2f (diff) | |
| download | rust-9a7ed3625f57ad21d646f835975ab42929214b60.tar.gz rust-9a7ed3625f57ad21d646f835975ab42929214b60.zip | |
Emit diagnostic for privately uninhabited uncovered witnesses.
Diffstat (limited to 'compiler/rustc_mir_build/src')
| -rw-r--r-- | compiler/rustc_mir_build/src/errors.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/pattern/check_match.rs | 18 |
2 files changed, 20 insertions, 0 deletions
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index dcdeaf008d6..7c0df201bc2 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -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>, diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index ca25f83e643..5559e8b3940 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -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, |
