new lint redundant_guards

This commit is contained in:
Centri3 2023-06-14 13:51:31 -05:00 committed by Catherine Flores
parent a44dcf80ef
commit 51b57723d1
16 changed files with 681 additions and 83 deletions

View file

@ -5190,6 +5190,7 @@ Released 2018-09-13
[`redundant_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_else
[`redundant_feature_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_feature_names
[`redundant_field_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names
[`redundant_guards`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_guards
[`redundant_locals`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_locals
[`redundant_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern
[`redundant_pattern_matching`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern_matching

View file

@ -308,6 +308,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS_INFO,
crate::matches::MATCH_WILD_ERR_ARM_INFO,
crate::matches::NEEDLESS_MATCH_INFO,
crate::matches::REDUNDANT_GUARDS_INFO,
crate::matches::REDUNDANT_PATTERN_MATCHING_INFO,
crate::matches::REST_PAT_IN_FULLY_BOUND_STRUCTS_INFO,
crate::matches::SIGNIFICANT_DROP_IN_SCRUTINEE_INFO,

View file

@ -76,7 +76,7 @@ impl<'a, 'tcx> Visitor<'tcx> for IncrementVisitor<'a, 'tcx> {
ExprKind::Assign(lhs, _, _) if lhs.hir_id == expr.hir_id => {
*state = IncrementVisitorVarState::DontWarn;
},
ExprKind::AddrOf(BorrowKind::Ref, mutability, _) if mutability == Mutability::Mut => {
ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, _) => {
*state = IncrementVisitorVarState::DontWarn;
},
_ => (),
@ -226,7 +226,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> {
InitializeVisitorState::DontWarn
}
},
ExprKind::AddrOf(BorrowKind::Ref, mutability, _) if mutability == Mutability::Mut => {
ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, _) => {
self.state = InitializeVisitorState::DontWarn;
},
_ => (),

View file

@ -16,6 +16,7 @@ mod match_wild_enum;
mod match_wild_err_arm;
mod needless_match;
mod overlapping_arms;
mod redundant_guards;
mod redundant_pattern_match;
mod rest_pat_in_fully_bound_struct;
mod significant_drop_in_scrutinee;
@ -936,6 +937,36 @@ declare_clippy_lint! {
"reimplementation of `filter`"
}
declare_clippy_lint! {
/// ### What it does
/// Checks for unnecessary guards in match expressions.
///
/// ### Why is this bad?
/// It's more complex and much less readable. Making it part of the pattern can improve
/// exhaustiveness checking as well.
///
/// ### Example
/// ```rust,ignore
/// match x {
/// Some(x) if matches!(x, Some(1)) => ..,
/// Some(x) if x == Some(2) => ..,
/// _ => todo!(),
/// }
/// ```
/// Use instead:
/// ```rust,ignore
/// match x {
/// Some(Some(1)) => ..,
/// Some(Some(2)) => ..,
/// _ => todo!(),
/// }
/// ```
#[clippy::version = "1.72.0"]
pub REDUNDANT_GUARDS,
complexity,
"checks for unnecessary guards in match expressions"
}
#[derive(Default)]
pub struct Matches {
msrv: Msrv,
@ -978,6 +1009,7 @@ impl_lint_pass!(Matches => [
TRY_ERR,
MANUAL_MAP,
MANUAL_FILTER,
REDUNDANT_GUARDS,
]);
impl<'tcx> LateLintPass<'tcx> for Matches {
@ -1025,6 +1057,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
needless_match::check_match(cx, ex, arms, expr);
match_on_vec_items::check(cx, ex);
match_str_case_mismatch::check(cx, ex, arms);
redundant_guards::check(cx, arms);
if !in_constant(cx, expr.hir_id) {
manual_unwrap_or::check(cx, expr, ex, arms);

View file

@ -0,0 +1,190 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::path_to_local;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::visitors::{for_each_expr, is_local_used};
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{Arm, BinOpKind, Expr, ExprKind, Guard, MatchSource, Node, Pat, PatKind};
use rustc_lint::LateContext;
use rustc_span::Span;
use std::ops::ControlFlow;
use super::REDUNDANT_GUARDS;
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
for outer_arm in arms {
let Some(guard) = outer_arm.guard else {
continue;
};
// `Some(x) if matches!(x, y)`
if let Guard::If(if_expr) = guard
&& let ExprKind::Match(
scrutinee,
[
arm,
Arm {
pat: Pat {
kind: PatKind::Wild,
..
},
..
},
],
MatchSource::Normal,
) = if_expr.kind
{
emit_redundant_guards(
cx,
outer_arm,
if_expr.span,
scrutinee,
arm.pat.span,
arm.guard,
);
}
// `Some(x) if let Some(2) = x`
else if let Guard::IfLet(let_expr) = guard {
emit_redundant_guards(
cx,
outer_arm,
let_expr.span,
let_expr.init,
let_expr.pat.span,
None,
);
}
// `Some(x) if x == Some(2)`
else if let Guard::If(if_expr) = guard
&& let ExprKind::Binary(bin_op, local, pat) = if_expr.kind
&& matches!(bin_op.node, BinOpKind::Eq)
&& expr_can_be_pat(cx, pat)
// Ensure they have the same type. If they don't, we'd need deref coercion which isn't
// possible (currently) in a pattern. In some cases, you can use something like
// `as_deref` or similar but in general, we shouldn't lint this as it'd create an
// extraordinary amount of FPs.
//
// This isn't necessary in the other two checks, as they must be a pattern already.
&& cx.typeck_results().expr_ty(local) == cx.typeck_results().expr_ty(pat)
{
emit_redundant_guards(
cx,
outer_arm,
if_expr.span,
local,
pat.span,
None,
);
}
}
}
fn get_pat_binding<'tcx>(cx: &LateContext<'tcx>, guard_expr: &Expr<'_>, outer_arm: &Arm<'tcx>) -> Option<(Span, bool)> {
if let Some(local) = path_to_local(guard_expr) && !is_local_used(cx, outer_arm.body, local) {
let mut span = None;
let mut multiple_bindings = false;
// `each_binding` gives the `HirId` of the `Pat` itself, not the binding
outer_arm.pat.walk(|pat| {
if let PatKind::Binding(_, hir_id, _, _) = pat.kind
&& hir_id == local
&& span.replace(pat.span).is_some()
{
multiple_bindings = true;
return false;
}
true
});
// Ignore bindings from or patterns, like `First(x) | Second(x, _) | Third(x, _, _)`
if !multiple_bindings {
return span.map(|span| {
(
span,
!matches!(cx.tcx.hir().get_parent(local), Node::PatField(_)),
)
});
}
}
None
}
fn emit_redundant_guards<'tcx>(
cx: &LateContext<'tcx>,
outer_arm: &Arm<'tcx>,
guard_span: Span,
local: &Expr<'_>,
pat_span: Span,
inner_guard: Option<Guard<'_>>,
) {
let mut app = Applicability::MaybeIncorrect;
let Some((pat_binding, can_use_shorthand)) = get_pat_binding(cx, local, outer_arm) else {
return;
};
span_lint_and_then(
cx,
REDUNDANT_GUARDS,
guard_span.source_callsite(),
"redundant guard",
|diag| {
let binding_replacement = snippet_with_applicability(cx, pat_span, "<binding_repl>", &mut app);
diag.multipart_suggestion_verbose(
"try",
vec![
if can_use_shorthand {
(pat_binding, binding_replacement.into_owned())
} else {
(pat_binding.shrink_to_hi(), format!(": {binding_replacement}"))
},
(
guard_span.source_callsite().with_lo(outer_arm.pat.span.hi()),
inner_guard.map_or_else(String::new, |guard| {
let (prefix, span) = match guard {
Guard::If(e) => ("if", e.span),
Guard::IfLet(l) => ("if let", l.span),
};
format!(
" {prefix} {}",
snippet_with_applicability(cx, span, "<guard>", &mut app),
)
}),
),
],
app,
);
},
);
}
/// Checks if the given `Expr` can also be represented as a `Pat`.
fn expr_can_be_pat(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
for_each_expr(expr, |expr| {
if match expr.kind {
ExprKind::ConstBlock(..) => cx.tcx.features().inline_const_pat,
ExprKind::Call(c, ..) if let ExprKind::Path(qpath) = c.kind => {
// Allow ctors
matches!(cx.qpath_res(&qpath, c.hir_id), Res::Def(DefKind::Ctor(..), ..))
},
ExprKind::Path(qpath) => {
matches!(
cx.qpath_res(&qpath, expr.hir_id),
Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Ctor(..), ..),
)
},
ExprKind::AddrOf(..)
| ExprKind::Array(..)
| ExprKind::Tup(..)
| ExprKind::Struct(..)
| ExprKind::Lit(..) => true,
_ => false,
} {
return ControlFlow::Continue(());
}
ControlFlow::Break(())
})
.is_none()
}

View file

@ -5,7 +5,8 @@
unreachable_patterns,
dead_code,
clippy::equatable_if_let,
clippy::needless_borrowed_reference
clippy::needless_borrowed_reference,
clippy::redundant_guards
)]
fn main() {

View file

@ -5,7 +5,8 @@
unreachable_patterns,
dead_code,
clippy::equatable_if_let,
clippy::needless_borrowed_reference
clippy::needless_borrowed_reference,
clippy::redundant_guards
)]
fn main() {

View file

@ -1,5 +1,5 @@
error: match expression looks like `matches!` macro
--> $DIR/match_expr_like_matches_macro.rs:15:14
--> $DIR/match_expr_like_matches_macro.rs:16:14
|
LL | let _y = match x {
| ______________^
@ -11,7 +11,7 @@ LL | | };
= note: `-D clippy::match-like-matches-macro` implied by `-D warnings`
error: redundant pattern matching, consider using `is_some()`
--> $DIR/match_expr_like_matches_macro.rs:21:14
--> $DIR/match_expr_like_matches_macro.rs:22:14
|
LL | let _w = match x {
| ______________^
@ -23,7 +23,7 @@ LL | | };
= note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
error: redundant pattern matching, consider using `is_none()`
--> $DIR/match_expr_like_matches_macro.rs:27:14
--> $DIR/match_expr_like_matches_macro.rs:28:14
|
LL | let _z = match x {
| ______________^
@ -33,7 +33,7 @@ LL | | };
| |_____^ help: try: `x.is_none()`
error: match expression looks like `matches!` macro
--> $DIR/match_expr_like_matches_macro.rs:33:15
--> $DIR/match_expr_like_matches_macro.rs:34:15
|
LL | let _zz = match x {
| _______________^
@ -43,13 +43,13 @@ LL | | };
| |_____^ help: try: `!matches!(x, Some(r) if r == 0)`
error: if let .. else expression looks like `matches!` macro
--> $DIR/match_expr_like_matches_macro.rs:39:16
--> $DIR/match_expr_like_matches_macro.rs:40:16
|
LL | let _zzz = if let Some(5) = x { true } else { false };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(x, Some(5))`
error: match expression looks like `matches!` macro
--> $DIR/match_expr_like_matches_macro.rs:63:20
--> $DIR/match_expr_like_matches_macro.rs:64:20
|
LL | let _ans = match x {
| ____________________^
@ -60,7 +60,7 @@ LL | | };
| |_________^ help: try: `matches!(x, E::A(_) | E::B(_))`
error: match expression looks like `matches!` macro
--> $DIR/match_expr_like_matches_macro.rs:73:20
--> $DIR/match_expr_like_matches_macro.rs:74:20
|
LL | let _ans = match x {
| ____________________^
@ -73,7 +73,7 @@ LL | | };
| |_________^ help: try: `matches!(x, E::A(_) | E::B(_))`
error: match expression looks like `matches!` macro
--> $DIR/match_expr_like_matches_macro.rs:83:20
--> $DIR/match_expr_like_matches_macro.rs:84:20
|
LL | let _ans = match x {
| ____________________^
@ -84,7 +84,7 @@ LL | | };
| |_________^ help: try: `!matches!(x, E::B(_) | E::C)`
error: match expression looks like `matches!` macro
--> $DIR/match_expr_like_matches_macro.rs:143:18
--> $DIR/match_expr_like_matches_macro.rs:144:18
|
LL | let _z = match &z {
| __________________^
@ -94,7 +94,7 @@ LL | | };
| |_________^ help: try: `matches!(z, Some(3))`
error: match expression looks like `matches!` macro
--> $DIR/match_expr_like_matches_macro.rs:152:18
--> $DIR/match_expr_like_matches_macro.rs:153:18
|
LL | let _z = match &z {
| __________________^
@ -104,7 +104,7 @@ LL | | };
| |_________^ help: try: `matches!(&z, Some(3))`
error: match expression looks like `matches!` macro
--> $DIR/match_expr_like_matches_macro.rs:169:21
--> $DIR/match_expr_like_matches_macro.rs:170:21
|
LL | let _ = match &z {
| _____________________^
@ -114,7 +114,7 @@ LL | | };
| |_____________^ help: try: `matches!(&z, AnEnum::X)`
error: match expression looks like `matches!` macro
--> $DIR/match_expr_like_matches_macro.rs:183:20
--> $DIR/match_expr_like_matches_macro.rs:184:20
|
LL | let _res = match &val {
| ____________________^
@ -124,7 +124,7 @@ LL | | };
| |_________^ help: try: `matches!(&val, &Some(ref _a))`
error: match expression looks like `matches!` macro
--> $DIR/match_expr_like_matches_macro.rs:195:20
--> $DIR/match_expr_like_matches_macro.rs:196:20
|
LL | let _res = match &val {
| ____________________^
@ -134,7 +134,7 @@ LL | | };
| |_________^ help: try: `matches!(&val, &Some(ref _a))`
error: match expression looks like `matches!` macro
--> $DIR/match_expr_like_matches_macro.rs:253:14
--> $DIR/match_expr_like_matches_macro.rs:254:14
|
LL | let _y = match Some(5) {
| ______________^

View file

@ -0,0 +1,133 @@
//@run-rustfix
//@aux-build:proc_macros.rs:proc-macro
#![feature(if_let_guard)]
#![allow(clippy::no_effect, unused)]
#![warn(clippy::redundant_guards)]
#[macro_use]
extern crate proc_macros;
struct A(u32);
struct B {
e: Option<A>,
}
struct C(u32, u32);
fn main() {
let c = C(1, 2);
match c {
C(x, 1) => ..,
_ => todo!(),
};
let x = Some(Some(1));
match x {
Some(Some(1)) if true => ..,
Some(Some(1)) => {
println!("a");
..
},
Some(Some(1)) => ..,
Some(Some(2)) => ..,
// Don't lint, since x is used in the body
Some(x) if let Some(1) = x => {
x;
..
}
_ => todo!(),
};
let y = 1;
match x {
// Don't inline these, since y is not from the pat
Some(x) if matches!(y, 1 if true) => ..,
Some(x) if let 1 = y => ..,
Some(x) if y == 2 => ..,
_ => todo!(),
};
let a = A(1);
match a {
_ if a.0 == 1 => {},
_ => todo!(),
}
let b = B { e: Some(A(0)) };
match b {
B { e: Some(A(2)) } => ..,
_ => todo!(),
};
// Do not lint, since we cannot represent this as a pattern (at least, without a conversion)
let v = Some(vec![1u8, 2, 3]);
match v {
Some(x) if x == [1] => {},
_ => {},
}
external! {
let x = Some(Some(1));
match x {
Some(x) if let Some(1) = x => ..,
_ => todo!(),
};
}
with_span! {
span
let x = Some(Some(1));
match x {
Some(x) if let Some(1) = x => ..,
_ => todo!(),
};
}
}
enum E {
A(&'static str),
B(&'static str),
C(&'static str),
}
fn i() {
match E::A("") {
// Do not lint
E::A(x) | E::B(x) | E::C(x) if x == "from an or pattern" => {},
E::A("not from an or pattern") => {},
_ => {},
};
}
fn h(v: Option<u32>) {
match v {
Some(0) => ..,
_ => ..,
};
}
// Do not lint
fn f(s: Option<std::ffi::OsString>) {
match s {
Some(x) if x == "a" => {},
_ => {},
}
}
struct S {
a: usize,
}
impl PartialEq for S {
fn eq(&self, _: &Self) -> bool {
true
}
}
impl Eq for S {}
static CONST_S: S = S { a: 1 };
fn g(opt_s: Option<S>) {
match opt_s {
Some(x) if x == CONST_S => {},
_ => {},
}
}

View file

@ -0,0 +1,133 @@
//@run-rustfix
//@aux-build:proc_macros.rs:proc-macro
#![feature(if_let_guard)]
#![allow(clippy::no_effect, unused)]
#![warn(clippy::redundant_guards)]
#[macro_use]
extern crate proc_macros;
struct A(u32);
struct B {
e: Option<A>,
}
struct C(u32, u32);
fn main() {
let c = C(1, 2);
match c {
C(x, y) if let 1 = y => ..,
_ => todo!(),
};
let x = Some(Some(1));
match x {
Some(x) if matches!(x, Some(1) if true) => ..,
Some(x) if matches!(x, Some(1)) => {
println!("a");
..
},
Some(x) if let Some(1) = x => ..,
Some(x) if x == Some(2) => ..,
// Don't lint, since x is used in the body
Some(x) if let Some(1) = x => {
x;
..
}
_ => todo!(),
};
let y = 1;
match x {
// Don't inline these, since y is not from the pat
Some(x) if matches!(y, 1 if true) => ..,
Some(x) if let 1 = y => ..,
Some(x) if y == 2 => ..,
_ => todo!(),
};
let a = A(1);
match a {
_ if a.0 == 1 => {},
_ => todo!(),
}
let b = B { e: Some(A(0)) };
match b {
B { e } if matches!(e, Some(A(2))) => ..,
_ => todo!(),
};
// Do not lint, since we cannot represent this as a pattern (at least, without a conversion)
let v = Some(vec![1u8, 2, 3]);
match v {
Some(x) if x == [1] => {},
_ => {},
}
external! {
let x = Some(Some(1));
match x {
Some(x) if let Some(1) = x => ..,
_ => todo!(),
};
}
with_span! {
span
let x = Some(Some(1));
match x {
Some(x) if let Some(1) = x => ..,
_ => todo!(),
};
}
}
enum E {
A(&'static str),
B(&'static str),
C(&'static str),
}
fn i() {
match E::A("") {
// Do not lint
E::A(x) | E::B(x) | E::C(x) if x == "from an or pattern" => {},
E::A(y) if y == "not from an or pattern" => {},
_ => {},
};
}
fn h(v: Option<u32>) {
match v {
x if matches!(x, Some(0)) => ..,
_ => ..,
};
}
// Do not lint
fn f(s: Option<std::ffi::OsString>) {
match s {
Some(x) if x == "a" => {},
_ => {},
}
}
struct S {
a: usize,
}
impl PartialEq for S {
fn eq(&self, _: &Self) -> bool {
true
}
}
impl Eq for S {}
static CONST_S: S = S { a: 1 };
fn g(opt_s: Option<S>) {
match opt_s {
Some(x) if x == CONST_S => {},
_ => {},
}
}

View file

@ -0,0 +1,98 @@
error: redundant guard
--> $DIR/redundant_guards.rs:21:20
|
LL | C(x, y) if let 1 = y => ..,
| ^^^^^^^^^
|
= note: `-D clippy::redundant-guards` implied by `-D warnings`
help: try
|
LL - C(x, y) if let 1 = y => ..,
LL + C(x, 1) => ..,
|
error: redundant guard
--> $DIR/redundant_guards.rs:27:20
|
LL | Some(x) if matches!(x, Some(1) if true) => ..,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: try
|
LL | Some(Some(1)) if true => ..,
| ~~~~~~~ ~~~~~~~
error: redundant guard
--> $DIR/redundant_guards.rs:28:20
|
LL | Some(x) if matches!(x, Some(1)) => {
| ^^^^^^^^^^^^^^^^^^^^
|
help: try
|
LL - Some(x) if matches!(x, Some(1)) => {
LL + Some(Some(1)) => {
|
error: redundant guard
--> $DIR/redundant_guards.rs:32:20
|
LL | Some(x) if let Some(1) = x => ..,
| ^^^^^^^^^^^^^^^
|
help: try
|
LL - Some(x) if let Some(1) = x => ..,
LL + Some(Some(1)) => ..,
|
error: redundant guard
--> $DIR/redundant_guards.rs:33:20
|
LL | Some(x) if x == Some(2) => ..,
| ^^^^^^^^^^^^
|
help: try
|
LL - Some(x) if x == Some(2) => ..,
LL + Some(Some(2)) => ..,
|
error: redundant guard
--> $DIR/redundant_guards.rs:56:20
|
LL | B { e } if matches!(e, Some(A(2))) => ..,
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: try
|
LL - B { e } if matches!(e, Some(A(2))) => ..,
LL + B { e: Some(A(2)) } => ..,
|
error: redundant guard
--> $DIR/redundant_guards.rs:93:20
|
LL | E::A(y) if y == "not from an or pattern" => {},
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: try
|
LL - E::A(y) if y == "not from an or pattern" => {},
LL + E::A("not from an or pattern") => {},
|
error: redundant guard
--> $DIR/redundant_guards.rs:100:14
|
LL | x if matches!(x, Some(0)) => ..,
| ^^^^^^^^^^^^^^^^^^^^
|
help: try
|
LL - x if matches!(x, Some(0)) => ..,
LL + Some(0) => ..,
|
error: aborting due to 8 previous errors

View file

@ -1,7 +1,12 @@
//@aux-build:proc_macro_derive.rs:proc-macro
#![warn(clippy::shadow_same, clippy::shadow_reuse, clippy::shadow_unrelated)]
#![allow(clippy::let_unit_value, clippy::needless_if, clippy::redundant_locals)]
#![allow(
clippy::let_unit_value,
clippy::needless_if,
clippy::redundant_guards,
clippy::redundant_locals
)]
extern crate proc_macro_derive;

View file

@ -1,278 +1,278 @@
error: `x` is shadowed by itself in `x`
--> $DIR/shadow.rs:19:9
--> $DIR/shadow.rs:24:9
|
LL | let x = x;
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:18:9
--> $DIR/shadow.rs:23:9
|
LL | let x = 1;
| ^
= note: `-D clippy::shadow-same` implied by `-D warnings`
error: `mut x` is shadowed by itself in `&x`
--> $DIR/shadow.rs:20:13
--> $DIR/shadow.rs:25:13
|
LL | let mut x = &x;
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:19:9
--> $DIR/shadow.rs:24:9
|
LL | let x = x;
| ^
error: `x` is shadowed by itself in `&mut x`
--> $DIR/shadow.rs:21:9
--> $DIR/shadow.rs:26:9
|
LL | let x = &mut x;
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:20:9
--> $DIR/shadow.rs:25:9
|
LL | let mut x = &x;
| ^^^^^
error: `x` is shadowed by itself in `*x`
--> $DIR/shadow.rs:22:9
--> $DIR/shadow.rs:27:9
|
LL | let x = *x;
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:21:9
--> $DIR/shadow.rs:26:9
|
LL | let x = &mut x;
| ^
error: `x` is shadowed
--> $DIR/shadow.rs:27:9
--> $DIR/shadow.rs:32:9
|
LL | let x = x.0;
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:26:9
--> $DIR/shadow.rs:31:9
|
LL | let x = ([[0]], ());
| ^
= note: `-D clippy::shadow-reuse` implied by `-D warnings`
error: `x` is shadowed
--> $DIR/shadow.rs:28:9
--> $DIR/shadow.rs:33:9
|
LL | let x = x[0];
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:27:9
--> $DIR/shadow.rs:32:9
|
LL | let x = x.0;
| ^
error: `x` is shadowed
--> $DIR/shadow.rs:29:10
--> $DIR/shadow.rs:34:10
|
LL | let [x] = x;
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:28:9
--> $DIR/shadow.rs:33:9
|
LL | let x = x[0];
| ^
error: `x` is shadowed
--> $DIR/shadow.rs:30:9
--> $DIR/shadow.rs:35:9
|
LL | let x = Some(x);
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:29:10
--> $DIR/shadow.rs:34:10
|
LL | let [x] = x;
| ^
error: `x` is shadowed
--> $DIR/shadow.rs:31:9
--> $DIR/shadow.rs:36:9
|
LL | let x = foo(x);
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:30:9
--> $DIR/shadow.rs:35:9
|
LL | let x = Some(x);
| ^
error: `x` is shadowed
--> $DIR/shadow.rs:32:9
--> $DIR/shadow.rs:37:9
|
LL | let x = || x;
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:31:9
--> $DIR/shadow.rs:36:9
|
LL | let x = foo(x);
| ^
error: `x` is shadowed
--> $DIR/shadow.rs:33:9
--> $DIR/shadow.rs:38:9
|
LL | let x = Some(1).map(|_| x)?;
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:32:9
--> $DIR/shadow.rs:37:9
|
LL | let x = || x;
| ^
error: `y` is shadowed
--> $DIR/shadow.rs:35:9
--> $DIR/shadow.rs:40:9
|
LL | let y = match y {
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:34:9
--> $DIR/shadow.rs:39:9
|
LL | let y = 1;
| ^
error: `x` shadows a previous, unrelated binding
--> $DIR/shadow.rs:50:9
--> $DIR/shadow.rs:55:9
|
LL | let x = 2;
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:49:9
--> $DIR/shadow.rs:54:9
|
LL | let x = 1;
| ^
= note: `-D clippy::shadow-unrelated` implied by `-D warnings`
error: `x` shadows a previous, unrelated binding
--> $DIR/shadow.rs:55:13
--> $DIR/shadow.rs:60:13
|
LL | let x = 1;
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:54:10
--> $DIR/shadow.rs:59:10
|
LL | fn f(x: u32) {
| ^
error: `x` shadows a previous, unrelated binding
--> $DIR/shadow.rs:60:14
--> $DIR/shadow.rs:65:14
|
LL | Some(x) => {
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:57:9
--> $DIR/shadow.rs:62:9
|
LL | let x = 1;
| ^
error: `x` shadows a previous, unrelated binding
--> $DIR/shadow.rs:61:17
--> $DIR/shadow.rs:66:17
|
LL | let x = 1;
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:60:14
--> $DIR/shadow.rs:65:14
|
LL | Some(x) => {
| ^
error: `x` shadows a previous, unrelated binding
--> $DIR/shadow.rs:65:17
--> $DIR/shadow.rs:70:17
|
LL | if let Some(x) = Some(1) {}
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:57:9
--> $DIR/shadow.rs:62:9
|
LL | let x = 1;
| ^
error: `x` shadows a previous, unrelated binding
--> $DIR/shadow.rs:66:20
--> $DIR/shadow.rs:71:20
|
LL | while let Some(x) = Some(1) {}
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:57:9
--> $DIR/shadow.rs:62:9
|
LL | let x = 1;
| ^
error: `x` shadows a previous, unrelated binding
--> $DIR/shadow.rs:67:15
--> $DIR/shadow.rs:72:15
|
LL | let _ = |[x]: [u32; 1]| {
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:57:9
--> $DIR/shadow.rs:62:9
|
LL | let x = 1;
| ^
error: `x` shadows a previous, unrelated binding
--> $DIR/shadow.rs:68:13
--> $DIR/shadow.rs:73:13
|
LL | let x = 1;
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:67:15
--> $DIR/shadow.rs:72:15
|
LL | let _ = |[x]: [u32; 1]| {
| ^
error: `y` is shadowed
--> $DIR/shadow.rs:71:17
--> $DIR/shadow.rs:76:17
|
LL | if let Some(y) = y {}
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:70:9
--> $DIR/shadow.rs:75:9
|
LL | let y = Some(1);
| ^
error: `_b` shadows a previous, unrelated binding
--> $DIR/shadow.rs:107:9
--> $DIR/shadow.rs:112:9
|
LL | let _b = _a;
| ^^
|
note: previous binding is here
--> $DIR/shadow.rs:106:28
--> $DIR/shadow.rs:111:28
|
LL | pub async fn foo2(_a: i32, _b: i64) {
| ^^
error: `x` shadows a previous, unrelated binding
--> $DIR/shadow.rs:113:21
--> $DIR/shadow.rs:118:21
|
LL | if let Some(x) = Some(1) { x } else { 1 }
| ^
|
note: previous binding is here
--> $DIR/shadow.rs:112:13
--> $DIR/shadow.rs:117:13
|
LL | let x = 1;
| ^

View file

@ -4,6 +4,7 @@
unused,
clippy::uninlined_format_args,
clippy::needless_if,
clippy::redundant_guards,
clippy::redundant_pattern_matching
)]
fn dummy() {}

View file

@ -4,6 +4,7 @@
unused,
clippy::uninlined_format_args,
clippy::needless_if,
clippy::redundant_guards,
clippy::redundant_pattern_matching
)]
fn dummy() {}

View file

@ -1,5 +1,5 @@
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> $DIR/single_match.rs:14:5
--> $DIR/single_match.rs:15:5
|
LL | / match x {
LL | | Some(y) => {
@ -18,7 +18,7 @@ LL ~ };
|
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> $DIR/single_match.rs:22:5
--> $DIR/single_match.rs:23:5
|
LL | / match x {
LL | | // Note the missing block braces.
@ -30,7 +30,7 @@ LL | | }
| |_____^ help: try: `if let Some(y) = x { println!("{:?}", y) }`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> $DIR/single_match.rs:31:5
--> $DIR/single_match.rs:32:5
|
LL | / match z {
LL | | (2..=3, 7..=9) => dummy(),
@ -39,7 +39,7 @@ LL | | };
| |_____^ help: try: `if let (2..=3, 7..=9) = z { dummy() }`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> $DIR/single_match.rs:60:5
--> $DIR/single_match.rs:61:5
|
LL | / match x {
LL | | Some(y) => dummy(),
@ -48,7 +48,7 @@ LL | | };
| |_____^ help: try: `if let Some(y) = x { dummy() }`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> $DIR/single_match.rs:65:5
--> $DIR/single_match.rs:66:5
|
LL | / match y {
LL | | Ok(y) => dummy(),
@ -57,7 +57,7 @@ LL | | };
| |_____^ help: try: `if let Ok(y) = y { dummy() }`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> $DIR/single_match.rs:72:5
--> $DIR/single_match.rs:73:5
|
LL | / match c {
LL | | Cow::Borrowed(..) => dummy(),
@ -66,7 +66,7 @@ LL | | };
| |_____^ help: try: `if let Cow::Borrowed(..) = c { dummy() }`
error: you seem to be trying to use `match` for an equality check. Consider using `if`
--> $DIR/single_match.rs:93:5
--> $DIR/single_match.rs:94:5
|
LL | / match x {
LL | | "test" => println!(),
@ -75,7 +75,7 @@ LL | | }
| |_____^ help: try: `if x == "test" { println!() }`
error: you seem to be trying to use `match` for an equality check. Consider using `if`
--> $DIR/single_match.rs:106:5
--> $DIR/single_match.rs:107:5
|
LL | / match x {
LL | | Foo::A => println!(),
@ -84,7 +84,7 @@ LL | | }
| |_____^ help: try: `if x == Foo::A { println!() }`
error: you seem to be trying to use `match` for an equality check. Consider using `if`
--> $DIR/single_match.rs:112:5
--> $DIR/single_match.rs:113:5
|
LL | / match x {
LL | | FOO_C => println!(),
@ -93,7 +93,7 @@ LL | | }
| |_____^ help: try: `if x == FOO_C { println!() }`
error: you seem to be trying to use `match` for an equality check. Consider using `if`
--> $DIR/single_match.rs:117:5
--> $DIR/single_match.rs:118:5
|
LL | / match &&x {
LL | | Foo::A => println!(),
@ -102,7 +102,7 @@ LL | | }
| |_____^ help: try: `if x == Foo::A { println!() }`
error: you seem to be trying to use `match` for an equality check. Consider using `if`
--> $DIR/single_match.rs:123:5
--> $DIR/single_match.rs:124:5
|
LL | / match &x {
LL | | Foo::A => println!(),
@ -111,7 +111,7 @@ LL | | }
| |_____^ help: try: `if x == &Foo::A { println!() }`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> $DIR/single_match.rs:140:5
--> $DIR/single_match.rs:141:5
|
LL | / match x {
LL | | Bar::A => println!(),
@ -120,7 +120,7 @@ LL | | }
| |_____^ help: try: `if let Bar::A = x { println!() }`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> $DIR/single_match.rs:148:5
--> $DIR/single_match.rs:149:5
|
LL | / match x {
LL | | None => println!(),
@ -129,7 +129,7 @@ LL | | };
| |_____^ help: try: `if let None = x { println!() }`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> $DIR/single_match.rs:170:5
--> $DIR/single_match.rs:171:5
|
LL | / match x {
LL | | (Some(_), _) => {},
@ -138,7 +138,7 @@ LL | | }
| |_____^ help: try: `if let (Some(_), _) = x {}`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> $DIR/single_match.rs:176:5
--> $DIR/single_match.rs:177:5
|
LL | / match x {
LL | | (Some(E::V), _) => todo!(),
@ -147,7 +147,7 @@ LL | | }
| |_____^ help: try: `if let (Some(E::V), _) = x { todo!() }`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> $DIR/single_match.rs:182:5
--> $DIR/single_match.rs:183:5
|
LL | / match (Some(42), Some(E::V), Some(42)) {
LL | | (.., Some(E::V), _) => {},
@ -156,7 +156,7 @@ LL | | }
| |_____^ help: try: `if let (.., Some(E::V), _) = (Some(42), Some(E::V), Some(42)) {}`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> $DIR/single_match.rs:254:5
--> $DIR/single_match.rs:255:5
|
LL | / match bar {
LL | | Some(v) => unsafe {
@ -176,7 +176,7 @@ LL + } }
|
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> $DIR/single_match.rs:262:5
--> $DIR/single_match.rs:263:5
|
LL | / match bar {
LL | | #[rustfmt::skip]