Suggest to set lint level on whole match
This commit is contained in:
parent
61d0fc7cf5
commit
f0e8330879
@ -221,8 +221,10 @@ mir_build_non_exhaustive_omitted_pattern = some variants are not matched explici
|
||||
.help = ensure that all variants are matched explicitly by adding the suggested match arms
|
||||
.note = the matched value is of type `{$scrut_ty}` and the `non_exhaustive_omitted_patterns` attribute was found
|
||||
|
||||
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
|
||||
mir_build_non_exhaustive_omitted_pattern_lint_on_arm = the lint level must be set on the whole match
|
||||
.help = it no longer has any effect to set the lint level on an individual match arm
|
||||
.label = remove this attribute
|
||||
.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
|
||||
|
@ -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 {
|
||||
#[label]
|
||||
pub lint_span: Span,
|
||||
#[suggestion(code = "#[{lint_level}({lint_name})]\n", applicability = "maybe-incorrect")]
|
||||
pub suggest_lint_on_match: Option<Span>,
|
||||
pub lint_level: &'static str,
|
||||
pub lint_name: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(mir_build_uncovered)]
|
||||
|
@ -285,7 +285,11 @@ impl<'thir, 'p, 'tcx> MatchVisitor<'thir, 'p, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn new_cx(&self, refutability: RefutableFlag) -> MatchCheckCtxt<'p, 'tcx> {
|
||||
fn new_cx(
|
||||
&self,
|
||||
refutability: RefutableFlag,
|
||||
match_span: Option<Span>,
|
||||
) -> MatchCheckCtxt<'p, 'tcx> {
|
||||
let refutable = match refutability {
|
||||
Irrefutable => false,
|
||||
Refutable => true,
|
||||
@ -295,6 +299,7 @@ impl<'thir, 'p, 'tcx> MatchVisitor<'thir, 'p, 'tcx> {
|
||||
param_env: self.param_env,
|
||||
module: self.tcx.parent_module(self.lint_level).to_def_id(),
|
||||
pattern_arena: &self.pattern_arena,
|
||||
match_span,
|
||||
refutable,
|
||||
}
|
||||
}
|
||||
@ -325,7 +330,7 @@ impl<'thir, 'p, 'tcx> MatchVisitor<'thir, 'p, 'tcx> {
|
||||
source: hir::MatchSource,
|
||||
expr_span: Span,
|
||||
) {
|
||||
let cx = self.new_cx(Refutable);
|
||||
let cx = self.new_cx(Refutable, Some(expr_span));
|
||||
|
||||
let mut tarms = Vec::with_capacity(arms.len());
|
||||
for &arm in arms {
|
||||
@ -448,7 +453,7 @@ impl<'thir, 'p, 'tcx> MatchVisitor<'thir, 'p, 'tcx> {
|
||||
pat: &Pat<'tcx>,
|
||||
refutability: RefutableFlag,
|
||||
) -> Result<(MatchCheckCtxt<'p, 'tcx>, UsefulnessReport<'p, 'tcx>), ErrorGuaranteed> {
|
||||
let cx = self.new_cx(refutability);
|
||||
let cx = self.new_cx(refutability, None);
|
||||
let pat = self.lower_pattern(&cx, pat)?;
|
||||
let arms = [MatchArm { pat, hir_id: self.lint_level, has_guard: false }];
|
||||
let report = compute_match_usefulness(&cx, &arms, self.lint_level, pat.ty(), pat.span());
|
||||
|
@ -340,6 +340,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,
|
||||
}
|
||||
@ -1179,16 +1181,21 @@ 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
|
||||
) {
|
||||
cx.tcx.emit_spanned_lint(
|
||||
NON_EXHAUSTIVE_OMITTED_PATTERNS,
|
||||
arm.hir_id,
|
||||
arm.pat.span(),
|
||||
NonExhaustiveOmittedPatternLintOnArm,
|
||||
);
|
||||
let (lint_level, lint_level_source) =
|
||||
cx.tcx.lint_level_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, arm.hir_id);
|
||||
if !matches!(lint_level, rustc_session::lint::Level::Allow) {
|
||||
let decorator = NonExhaustiveOmittedPatternLintOnArm {
|
||||
lint_span: lint_level_source.span(),
|
||||
suggest_lint_on_match: cx.match_span.map(|span| span.shrink_to_lo()),
|
||||
lint_level: lint_level.as_str(),
|
||||
lint_name: "non_exhaustive_omitted_patterns",
|
||||
};
|
||||
|
||||
use rustc_errors::DecorateLint;
|
||||
let mut err = cx.tcx.sess.struct_span_warn(arm.pat.span(), "");
|
||||
err.set_primary_message(decorator.msg());
|
||||
decorator.decorate_lint(&mut err);
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,44 +26,50 @@ note: the lint level is defined here
|
||||
LL | #[cfg_attr(lint, deny(non_exhaustive_omitted_patterns))]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: the `non_exhaustive_omitted_pattern` lint level must be set on the whole match
|
||||
warning: the lint level must be set on the whole match
|
||||
--> $DIR/omitted-patterns-dont-lint-on-arm.rs:34:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^
|
||||
|
|
||||
= help: it used to make sense to set the lint level on an individual match arm, but that is no longer the case
|
||||
note: the lint level is defined here
|
||||
--> $DIR/omitted-patterns-dont-lint-on-arm.rs:33:16
|
||||
|
|
||||
LL | #[deny(non_exhaustive_omitted_patterns)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
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
|
||||
|
|
||||
| ------------------------------- remove this attribute
|
||||
LL | _ => {}
|
||||
| ^
|
||||
|
|
||||
= help: it used to make sense to set the lint level on an individual match arm, but that is no longer the case
|
||||
note: the lint level is defined here
|
||||
--> $DIR/omitted-patterns-dont-lint-on-arm.rs:40:31
|
||||
= help: it no longer has any effect to set the lint level on an individual match arm
|
||||
help: set the lint level on the whole match
|
||||
|
|
||||
LL + #[deny(non_exhaustive_omitted_patterns)]
|
||||
LL | match val {
|
||||
|
|
||||
|
||||
warning: the lint level must be set on the whole match
|
||||
--> $DIR/omitted-patterns-dont-lint-on-arm.rs:42:9
|
||||
|
|
||||
LL | #[cfg_attr(lint, deny(non_exhaustive_omitted_patterns))]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
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
|
||||
|
|
||||
| ------------------------------- remove this attribute
|
||||
LL | _ => {}
|
||||
| ^
|
||||
|
|
||||
= help: it used to make sense to set the lint level on an individual match arm, but that is no longer the case
|
||||
note: the lint level is defined here
|
||||
--> $DIR/omitted-patterns-dont-lint-on-arm.rs:47:31
|
||||
= help: it no longer has any effect to set the lint level on an individual match arm
|
||||
help: set the lint level on the whole match
|
||||
|
|
||||
LL + #[deny(non_exhaustive_omitted_patterns)]
|
||||
LL | match val {
|
||||
|
|
||||
|
||||
warning: the lint level must be set on the whole match
|
||||
--> $DIR/omitted-patterns-dont-lint-on-arm.rs:50:9
|
||||
|
|
||||
LL | #[cfg_attr(lint, warn(non_exhaustive_omitted_patterns))]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ------------------------------- remove this attribute
|
||||
LL | _ => {}
|
||||
| ^
|
||||
|
|
||||
= help: it no longer has any effect to set the lint level on an individual match arm
|
||||
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
|
||||
error: aborting due to 2 previous errors; 3 warnings emitted
|
||||
|
||||
|
@ -12,18 +12,20 @@ note: the lint level is defined here
|
||||
LL | #[deny(non_exhaustive_omitted_patterns)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: the `non_exhaustive_omitted_pattern` lint level must be set on the whole match
|
||||
warning: the lint level must be set on the whole match
|
||||
--> $DIR/omitted-patterns-dont-lint-on-arm.rs:34:9
|
||||
|
|
||||
LL | #[deny(non_exhaustive_omitted_patterns)]
|
||||
| ------------------------------- remove this attribute
|
||||
LL | _ => {}
|
||||
| ^
|
||||
|
|
||||
= help: it used to make sense to set the lint level on an individual match arm, but that is no longer the case
|
||||
note: the lint level is defined here
|
||||
--> $DIR/omitted-patterns-dont-lint-on-arm.rs:33:16
|
||||
= help: it no longer has any effect to set the lint level on an individual match arm
|
||||
help: set the lint level on the whole match
|
||||
|
|
||||
LL + #[deny(non_exhaustive_omitted_patterns)]
|
||||
LL | match val {
|
||||
|
|
||||
LL | #[deny(non_exhaustive_omitted_patterns)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
|
@ -31,20 +31,23 @@ fn main() {
|
||||
NonExhaustiveEnum::Unit => {}
|
||||
NonExhaustiveEnum::Tuple(_) => {}
|
||||
#[deny(non_exhaustive_omitted_patterns)]
|
||||
_ => {} //~ ERROR lint level must be set on the whole match
|
||||
_ => {}
|
||||
}
|
||||
//~^^ WARN lint level must be set on the whole match
|
||||
|
||||
match val {
|
||||
NonExhaustiveEnum::Unit => {}
|
||||
NonExhaustiveEnum::Tuple(_) => {}
|
||||
#[cfg_attr(lint, deny(non_exhaustive_omitted_patterns))]
|
||||
_ => {} //[lint]~ ERROR lint level must be set on the whole match
|
||||
_ => {}
|
||||
}
|
||||
//[lint]~^^ WARN lint level must be set on the whole match
|
||||
|
||||
match val {
|
||||
NonExhaustiveEnum::Unit => {}
|
||||
NonExhaustiveEnum::Tuple(_) => {}
|
||||
#[cfg_attr(lint, warn(non_exhaustive_omitted_patterns))]
|
||||
_ => {} //[lint]~ WARN lint level must be set on the whole match
|
||||
_ => {}
|
||||
}
|
||||
//[lint]~^^ WARN lint level must be set on the whole match
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user