Skip to content

Commit feac3b9

Browse files
committed
Suggest to set lint level on whole match
1 parent 485b566 commit feac3b9

File tree

6 files changed

+49
-11
lines changed

6 files changed

+49
-11
lines changed

compiler/rustc_mir_build/messages.ftl

+1
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ mir_build_non_exhaustive_omitted_pattern = some variants are not matched explici
223223
224224
mir_build_non_exhaustive_omitted_pattern_lint_on_arm = the `non_exhaustive_omitted_pattern` lint level must be set on the whole match
225225
.help = it used to make sense to set the lint level on an individual match arm, but that is no longer the case
226+
.suggestion = set the lint level on the whole match
226227
227228
mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type `{$ty}` is non-empty
228229
.def_note = `{$peeled_ty}` defined here

compiler/rustc_mir_build/src/errors.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,14 @@ pub(crate) struct NonExhaustiveOmittedPattern<'tcx> {
792792
#[derive(LintDiagnostic)]
793793
#[diag(mir_build_non_exhaustive_omitted_pattern_lint_on_arm)]
794794
#[help]
795-
pub(crate) struct NonExhaustiveOmittedPatternLintOnArm;
795+
pub(crate) struct NonExhaustiveOmittedPatternLintOnArm {
796+
#[suggestion(
797+
code = "#[{lint_level}(non_exhaustive_omitted_patterns)]\n",
798+
applicability = "maybe-incorrect"
799+
)]
800+
pub suggest_lint_on_match: Option<Span>,
801+
pub lint_level: &'static str,
802+
}
796803

797804
#[derive(Subdiagnostic)]
798805
#[label(mir_build_uncovered)]

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,18 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
218218
cx.pattern_arena.alloc(DeconstructedPat::from_pat(cx, &pattern))
219219
}
220220

221-
fn new_cx(&self, hir_id: HirId, refutable: bool) -> MatchCheckCtxt<'p, 'tcx> {
221+
fn new_cx(
222+
&self,
223+
hir_id: HirId,
224+
refutable: bool,
225+
match_span: Option<Span>,
226+
) -> MatchCheckCtxt<'p, 'tcx> {
222227
MatchCheckCtxt {
223228
tcx: self.tcx,
224229
param_env: self.param_env,
225230
module: self.tcx.parent_module(hir_id).to_def_id(),
226231
pattern_arena: &self.pattern_arena,
232+
match_span,
227233
refutable,
228234
}
229235
}
@@ -238,7 +244,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
238244
return;
239245
}
240246
self.check_patterns(pat, Refutable);
241-
let mut cx = self.new_cx(self.lint_level, true);
247+
let mut cx = self.new_cx(self.lint_level, true, None);
242248
let tpat = self.lower_pattern(&mut cx, pat);
243249
self.check_let_reachability(&mut cx, self.lint_level, source, tpat, span);
244250
}
@@ -250,7 +256,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
250256
source: hir::MatchSource,
251257
expr_span: Span,
252258
) {
253-
let mut cx = self.new_cx(self.lint_level, true);
259+
let mut cx = self.new_cx(self.lint_level, true, Some(expr_span));
254260

255261
for &arm in arms {
256262
// Check the arm for some things unrelated to exhaustiveness.
@@ -363,7 +369,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
363369
error = Err(err);
364370
return None;
365371
}
366-
let mut ncx = self.new_cx(local_lint_level, true);
372+
let mut ncx = self.new_cx(local_lint_level, true, None);
367373
let tpat = self.lower_pattern(&mut ncx, pat);
368374
let refutable = !is_let_irrefutable(&mut ncx, local_lint_level, tpat);
369375
Some((expr.span, refutable))
@@ -468,7 +474,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
468474
return;
469475
}
470476

471-
let mut cx = self.new_cx(self.lint_level, false);
477+
let mut cx = self.new_cx(self.lint_level, false, None);
472478

473479
let pattern = self.lower_pattern(&mut cx, pat);
474480
let pattern_ty = pattern.ty();

compiler/rustc_mir_build/src/thir/pattern/usefulness.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,8 @@ pub(crate) struct MatchCheckCtxt<'p, 'tcx> {
339339
pub(crate) module: DefId,
340340
pub(crate) param_env: ty::ParamEnv<'tcx>,
341341
pub(crate) pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>,
342+
/// The span of the whole match, if applicable.
343+
pub(crate) match_span: Option<Span>,
342344
/// Only produce `NON_EXHAUSTIVE_OMITTED_PATTERNS` lint on refutable patterns.
343345
pub(crate) refutable: bool,
344346
}
@@ -1178,15 +1180,17 @@ pub(crate) fn compute_match_usefulness<'p, 'tcx>(
11781180
// arm. This no longer makes sense so we warn users, to avoid silently breaking their
11791181
// usage of the lint.
11801182
for arm in arms {
1181-
if !matches!(
1182-
cx.tcx.lint_level_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, arm.hir_id).0,
1183-
rustc_session::lint::Level::Allow
1184-
) {
1183+
let lint_level =
1184+
cx.tcx.lint_level_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, arm.hir_id).0;
1185+
if !matches!(lint_level, rustc_session::lint::Level::Allow) {
11851186
cx.tcx.emit_spanned_lint(
11861187
NON_EXHAUSTIVE_OMITTED_PATTERNS,
11871188
arm.hir_id,
11881189
arm.pat.span(),
1189-
NonExhaustiveOmittedPatternLintOnArm,
1190+
NonExhaustiveOmittedPatternLintOnArm {
1191+
suggest_lint_on_match: cx.match_span,
1192+
lint_level: lint_level.as_str(),
1193+
},
11901194
);
11911195
}
11921196
}

tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns-dont-lint-on-arm.lint.stderr

+15
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ note: the lint level is defined here
3838
|
3939
LL | #[deny(non_exhaustive_omitted_patterns)]
4040
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41+
help: set the lint level on the whole match
42+
|
43+
LL + #[deny(non_exhaustive_omitted_patterns)]
44+
LL | match val {
45+
|
4146

4247
error: the `non_exhaustive_omitted_pattern` lint level must be set on the whole match
4348
--> $DIR/omitted-patterns-dont-lint-on-arm.rs:41:9
@@ -51,6 +56,11 @@ note: the lint level is defined here
5156
|
5257
LL | #[cfg_attr(lint, deny(non_exhaustive_omitted_patterns))]
5358
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
59+
help: set the lint level on the whole match
60+
|
61+
LL + #[deny(non_exhaustive_omitted_patterns)]
62+
LL | match val {
63+
|
5464

5565
warning: the `non_exhaustive_omitted_pattern` lint level must be set on the whole match
5666
--> $DIR/omitted-patterns-dont-lint-on-arm.rs:48:9
@@ -64,6 +74,11 @@ note: the lint level is defined here
6474
|
6575
LL | #[cfg_attr(lint, warn(non_exhaustive_omitted_patterns))]
6676
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
77+
help: set the lint level on the whole match
78+
|
79+
LL + #[warn(non_exhaustive_omitted_patterns)]
80+
LL | match val {
81+
|
6782

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

tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns-dont-lint-on-arm.normal.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ note: the lint level is defined here
2424
|
2525
LL | #[deny(non_exhaustive_omitted_patterns)]
2626
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
27+
help: set the lint level on the whole match
28+
|
29+
LL + #[deny(non_exhaustive_omitted_patterns)]
30+
LL | match val {
31+
|
2732

2833
error: aborting due to 2 previous errors
2934

0 commit comments

Comments
 (0)