Suggest to set lint level on whole match
This commit is contained in:
parent
61d0fc7cf5
commit
f0e8330879
7 changed files with 84 additions and 52 deletions
|
@ -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
|
.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
|
.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
|
mir_build_non_exhaustive_omitted_pattern_lint_on_arm = the 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
|
.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
|
mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type `{$ty}` is non-empty
|
||||||
.def_note = `{$peeled_ty}` defined here
|
.def_note = `{$peeled_ty}` defined here
|
||||||
|
|
|
@ -792,7 +792,14 @@ pub(crate) struct NonExhaustiveOmittedPattern<'tcx> {
|
||||||
#[derive(LintDiagnostic)]
|
#[derive(LintDiagnostic)]
|
||||||
#[diag(mir_build_non_exhaustive_omitted_pattern_lint_on_arm)]
|
#[diag(mir_build_non_exhaustive_omitted_pattern_lint_on_arm)]
|
||||||
#[help]
|
#[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)]
|
#[derive(Subdiagnostic)]
|
||||||
#[label(mir_build_uncovered)]
|
#[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 {
|
let refutable = match refutability {
|
||||||
Irrefutable => false,
|
Irrefutable => false,
|
||||||
Refutable => true,
|
Refutable => true,
|
||||||
|
@ -295,6 +299,7 @@ impl<'thir, 'p, 'tcx> MatchVisitor<'thir, 'p, 'tcx> {
|
||||||
param_env: self.param_env,
|
param_env: self.param_env,
|
||||||
module: self.tcx.parent_module(self.lint_level).to_def_id(),
|
module: self.tcx.parent_module(self.lint_level).to_def_id(),
|
||||||
pattern_arena: &self.pattern_arena,
|
pattern_arena: &self.pattern_arena,
|
||||||
|
match_span,
|
||||||
refutable,
|
refutable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -325,7 +330,7 @@ impl<'thir, 'p, 'tcx> MatchVisitor<'thir, 'p, 'tcx> {
|
||||||
source: hir::MatchSource,
|
source: hir::MatchSource,
|
||||||
expr_span: Span,
|
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());
|
let mut tarms = Vec::with_capacity(arms.len());
|
||||||
for &arm in arms {
|
for &arm in arms {
|
||||||
|
@ -448,7 +453,7 @@ impl<'thir, 'p, 'tcx> MatchVisitor<'thir, 'p, 'tcx> {
|
||||||
pat: &Pat<'tcx>,
|
pat: &Pat<'tcx>,
|
||||||
refutability: RefutableFlag,
|
refutability: RefutableFlag,
|
||||||
) -> Result<(MatchCheckCtxt<'p, 'tcx>, UsefulnessReport<'p, 'tcx>), ErrorGuaranteed> {
|
) -> 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 pat = self.lower_pattern(&cx, pat)?;
|
||||||
let arms = [MatchArm { pat, hir_id: self.lint_level, has_guard: false }];
|
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());
|
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) module: DefId,
|
||||||
pub(crate) param_env: ty::ParamEnv<'tcx>,
|
pub(crate) param_env: ty::ParamEnv<'tcx>,
|
||||||
pub(crate) pattern_arena: &'p TypedArena<DeconstructedPat<'p, '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.
|
/// Only produce `NON_EXHAUSTIVE_OMITTED_PATTERNS` lint on refutable patterns.
|
||||||
pub(crate) refutable: bool,
|
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
|
// arm. This no longer makes sense so we warn users, to avoid silently breaking their
|
||||||
// usage of the lint.
|
// usage of the lint.
|
||||||
for arm in arms {
|
for arm in arms {
|
||||||
if !matches!(
|
let (lint_level, lint_level_source) =
|
||||||
cx.tcx.lint_level_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, arm.hir_id).0,
|
cx.tcx.lint_level_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, arm.hir_id);
|
||||||
rustc_session::lint::Level::Allow
|
if !matches!(lint_level, rustc_session::lint::Level::Allow) {
|
||||||
) {
|
let decorator = NonExhaustiveOmittedPatternLintOnArm {
|
||||||
cx.tcx.emit_spanned_lint(
|
lint_span: lint_level_source.span(),
|
||||||
NON_EXHAUSTIVE_OMITTED_PATTERNS,
|
suggest_lint_on_match: cx.match_span.map(|span| span.shrink_to_lo()),
|
||||||
arm.hir_id,
|
lint_level: lint_level.as_str(),
|
||||||
arm.pat.span(),
|
lint_name: "non_exhaustive_omitted_patterns",
|
||||||
NonExhaustiveOmittedPatternLintOnArm,
|
};
|
||||||
);
|
|
||||||
|
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))]
|
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
|
--> $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)]
|
LL | #[deny(non_exhaustive_omitted_patterns)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ------------------------------- remove this attribute
|
||||||
|
|
||||||
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
|
|
||||||
|
|
|
||||||
LL | _ => {}
|
LL | _ => {}
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= help: it used to make sense to set the lint level on an individual match arm, but that is no longer the case
|
= help: it no longer has any effect to set the lint level on an individual match arm
|
||||||
note: the lint level is defined here
|
help: set the lint level on the whole match
|
||||||
--> $DIR/omitted-patterns-dont-lint-on-arm.rs:40:31
|
|
|
||||||
|
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))]
|
LL | #[cfg_attr(lint, deny(non_exhaustive_omitted_patterns))]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ------------------------------- remove this attribute
|
||||||
|
|
||||||
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
|
|
||||||
|
|
|
||||||
LL | _ => {}
|
LL | _ => {}
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= help: it used to make sense to set the lint level on an individual match arm, but that is no longer the case
|
= help: it no longer has any effect to set the lint level on an individual match arm
|
||||||
note: the lint level is defined here
|
help: set the lint level on the whole match
|
||||||
--> $DIR/omitted-patterns-dont-lint-on-arm.rs:47:31
|
|
|
||||||
|
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))]
|
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)]
|
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
|
--> $DIR/omitted-patterns-dont-lint-on-arm.rs:34:9
|
||||||
|
|
|
|
||||||
|
LL | #[deny(non_exhaustive_omitted_patterns)]
|
||||||
|
| ------------------------------- remove this attribute
|
||||||
LL | _ => {}
|
LL | _ => {}
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= help: it used to make sense to set the lint level on an individual match arm, but that is no longer the case
|
= help: it no longer has any effect to set the lint level on an individual match arm
|
||||||
note: the lint level is defined here
|
help: set the lint level on the whole match
|
||||||
--> $DIR/omitted-patterns-dont-lint-on-arm.rs:33:16
|
|
|
||||||
|
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::Unit => {}
|
||||||
NonExhaustiveEnum::Tuple(_) => {}
|
NonExhaustiveEnum::Tuple(_) => {}
|
||||||
#[deny(non_exhaustive_omitted_patterns)]
|
#[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 {
|
match val {
|
||||||
NonExhaustiveEnum::Unit => {}
|
NonExhaustiveEnum::Unit => {}
|
||||||
NonExhaustiveEnum::Tuple(_) => {}
|
NonExhaustiveEnum::Tuple(_) => {}
|
||||||
#[cfg_attr(lint, deny(non_exhaustive_omitted_patterns))]
|
#[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 {
|
match val {
|
||||||
NonExhaustiveEnum::Unit => {}
|
NonExhaustiveEnum::Unit => {}
|
||||||
NonExhaustiveEnum::Tuple(_) => {}
|
NonExhaustiveEnum::Tuple(_) => {}
|
||||||
#[cfg_attr(lint, warn(non_exhaustive_omitted_patterns))]
|
#[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…
Add table
Add a link
Reference in a new issue