Skip to content

Commit

Permalink
Suggest to set lint level on whole match
Browse files Browse the repository at this point in the history
  • Loading branch information
Nadrieril committed Nov 1, 2023
1 parent 485b566 commit feac3b9
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 11 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_mir_build/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ mir_build_non_exhaustive_omitted_pattern = some variants are not matched explici
mir_build_non_exhaustive_omitted_pattern_lint_on_arm = the `non_exhaustive_omitted_pattern` lint level must be set on the whole match
.help = it used to make sense to set the lint level on an individual match arm, but that is no longer the case
.suggestion = set the lint level on the whole match
mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type `{$ty}` is non-empty
.def_note = `{$peeled_ty}` defined here
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_mir_build/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,14 @@ pub(crate) struct NonExhaustiveOmittedPattern<'tcx> {
#[derive(LintDiagnostic)]
#[diag(mir_build_non_exhaustive_omitted_pattern_lint_on_arm)]
#[help]
pub(crate) struct NonExhaustiveOmittedPatternLintOnArm;
pub(crate) struct NonExhaustiveOmittedPatternLintOnArm {
#[suggestion(
code = "#[{lint_level}(non_exhaustive_omitted_patterns)]\n",
applicability = "maybe-incorrect"
)]
pub suggest_lint_on_match: Option<Span>,
pub lint_level: &'static str,
}

#[derive(Subdiagnostic)]
#[label(mir_build_uncovered)]
Expand Down
16 changes: 11 additions & 5 deletions compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,18 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
cx.pattern_arena.alloc(DeconstructedPat::from_pat(cx, &pattern))
}

fn new_cx(&self, hir_id: HirId, refutable: bool) -> MatchCheckCtxt<'p, 'tcx> {
fn new_cx(
&self,
hir_id: HirId,
refutable: bool,
match_span: Option<Span>,
) -> MatchCheckCtxt<'p, 'tcx> {
MatchCheckCtxt {
tcx: self.tcx,
param_env: self.param_env,
module: self.tcx.parent_module(hir_id).to_def_id(),
pattern_arena: &self.pattern_arena,
match_span,
refutable,
}
}
Expand All @@ -238,7 +244,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
return;
}
self.check_patterns(pat, Refutable);
let mut cx = self.new_cx(self.lint_level, true);
let mut cx = self.new_cx(self.lint_level, true, None);
let tpat = self.lower_pattern(&mut cx, pat);
self.check_let_reachability(&mut cx, self.lint_level, source, tpat, span);
}
Expand All @@ -250,7 +256,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
source: hir::MatchSource,
expr_span: Span,
) {
let mut cx = self.new_cx(self.lint_level, true);
let mut cx = self.new_cx(self.lint_level, true, Some(expr_span));

for &arm in arms {
// Check the arm for some things unrelated to exhaustiveness.
Expand Down Expand Up @@ -363,7 +369,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
error = Err(err);
return None;
}
let mut ncx = self.new_cx(local_lint_level, true);
let mut ncx = self.new_cx(local_lint_level, true, None);
let tpat = self.lower_pattern(&mut ncx, pat);
let refutable = !is_let_irrefutable(&mut ncx, local_lint_level, tpat);
Some((expr.span, refutable))
Expand Down Expand Up @@ -468,7 +474,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
return;
}

let mut cx = self.new_cx(self.lint_level, false);
let mut cx = self.new_cx(self.lint_level, false, None);

let pattern = self.lower_pattern(&mut cx, pat);
let pattern_ty = pattern.ty();
Expand Down
14 changes: 9 additions & 5 deletions compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ pub(crate) struct MatchCheckCtxt<'p, 'tcx> {
pub(crate) module: DefId,
pub(crate) param_env: ty::ParamEnv<'tcx>,
pub(crate) pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>,
/// The span of the whole match, if applicable.
pub(crate) match_span: Option<Span>,
/// Only produce `NON_EXHAUSTIVE_OMITTED_PATTERNS` lint on refutable patterns.
pub(crate) refutable: bool,
}
Expand Down Expand Up @@ -1178,15 +1180,17 @@ pub(crate) fn compute_match_usefulness<'p, 'tcx>(
// arm. This no longer makes sense so we warn users, to avoid silently breaking their
// usage of the lint.
for arm in arms {
if !matches!(
cx.tcx.lint_level_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, arm.hir_id).0,
rustc_session::lint::Level::Allow
) {
let lint_level =
cx.tcx.lint_level_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, arm.hir_id).0;
if !matches!(lint_level, rustc_session::lint::Level::Allow) {
cx.tcx.emit_spanned_lint(
NON_EXHAUSTIVE_OMITTED_PATTERNS,
arm.hir_id,
arm.pat.span(),
NonExhaustiveOmittedPatternLintOnArm,
NonExhaustiveOmittedPatternLintOnArm {
suggest_lint_on_match: cx.match_span,
lint_level: lint_level.as_str(),
},
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ note: the lint level is defined here
|
LL | #[deny(non_exhaustive_omitted_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: set the lint level on the whole match
|
LL + #[deny(non_exhaustive_omitted_patterns)]
LL | match val {
|

error: the `non_exhaustive_omitted_pattern` lint level must be set on the whole match
--> $DIR/omitted-patterns-dont-lint-on-arm.rs:41:9
Expand All @@ -51,6 +56,11 @@ note: the lint level is defined here
|
LL | #[cfg_attr(lint, deny(non_exhaustive_omitted_patterns))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: set the lint level on the whole match
|
LL + #[deny(non_exhaustive_omitted_patterns)]
LL | match val {
|

warning: the `non_exhaustive_omitted_pattern` lint level must be set on the whole match
--> $DIR/omitted-patterns-dont-lint-on-arm.rs:48:9
Expand All @@ -64,6 +74,11 @@ note: the lint level is defined here
|
LL | #[cfg_attr(lint, warn(non_exhaustive_omitted_patterns))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: set the lint level on the whole match
|
LL + #[warn(non_exhaustive_omitted_patterns)]
LL | match val {
|

error: aborting due to 4 previous errors; 1 warning emitted

Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ note: the lint level is defined here
|
LL | #[deny(non_exhaustive_omitted_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: set the lint level on the whole match
|
LL + #[deny(non_exhaustive_omitted_patterns)]
LL | match val {
|

error: aborting due to 2 previous errors

0 comments on commit feac3b9

Please sign in to comment.