mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-24 13:43:17 +00:00
Auto merge of #9855 - Alexendoo:needless-borrowed-ref-extra, r=xFrednet
Extend `needless_borrowed_reference` to structs and tuples, ignore _ changelog: [`needless_borrowed_reference`]: Lint struct and tuple patterns, and patterns containing `_` Now lints patterns like ```rust &(ref a, ref b) &Tuple(ref a, ref b) &Struct { ref a, ref b } &(ref a, _) ```
This commit is contained in:
commit
d019fd9780
13 changed files with 357 additions and 115 deletions
|
@ -250,7 +250,7 @@ impl LateLintPass<'_> for EnumVariantNames {
|
|||
let item_name = item.ident.name.as_str();
|
||||
let item_camel = to_camel_case(item_name);
|
||||
if !item.span.from_expansion() && is_present_in_source(cx, item.span) {
|
||||
if let Some(&(ref mod_name, ref mod_camel)) = self.modules.last() {
|
||||
if let Some((mod_name, mod_camel)) = self.modules.last() {
|
||||
// constants don't have surrounding modules
|
||||
if !mod_camel.is_empty() {
|
||||
if mod_name == &item.ident.name {
|
||||
|
|
|
@ -62,58 +62,54 @@ impl IntPlusOne {
|
|||
fn check_binop(cx: &EarlyContext<'_>, binop: BinOpKind, lhs: &Expr, rhs: &Expr) -> Option<String> {
|
||||
match (binop, &lhs.kind, &rhs.kind) {
|
||||
// case where `x - 1 >= ...` or `-1 + x >= ...`
|
||||
(BinOpKind::Ge, &ExprKind::Binary(ref lhskind, ref lhslhs, ref lhsrhs), _) => {
|
||||
(BinOpKind::Ge, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) => {
|
||||
match (lhskind.node, &lhslhs.kind, &lhsrhs.kind) {
|
||||
// `-1 + x`
|
||||
(BinOpKind::Add, &ExprKind::Lit(ref lit), _) if Self::check_lit(lit, -1) => {
|
||||
(BinOpKind::Add, ExprKind::Lit(lit), _) if Self::check_lit(lit, -1) => {
|
||||
Self::generate_recommendation(cx, binop, lhsrhs, rhs, Side::Lhs)
|
||||
},
|
||||
// `x - 1`
|
||||
(BinOpKind::Sub, _, &ExprKind::Lit(ref lit)) if Self::check_lit(lit, 1) => {
|
||||
(BinOpKind::Sub, _, ExprKind::Lit(lit)) if Self::check_lit(lit, 1) => {
|
||||
Self::generate_recommendation(cx, binop, lhslhs, rhs, Side::Lhs)
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
},
|
||||
// case where `... >= y + 1` or `... >= 1 + y`
|
||||
(BinOpKind::Ge, _, &ExprKind::Binary(ref rhskind, ref rhslhs, ref rhsrhs))
|
||||
if rhskind.node == BinOpKind::Add =>
|
||||
{
|
||||
(BinOpKind::Ge, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) if rhskind.node == BinOpKind::Add => {
|
||||
match (&rhslhs.kind, &rhsrhs.kind) {
|
||||
// `y + 1` and `1 + y`
|
||||
(&ExprKind::Lit(ref lit), _) if Self::check_lit(lit, 1) => {
|
||||
(ExprKind::Lit(lit), _) if Self::check_lit(lit, 1) => {
|
||||
Self::generate_recommendation(cx, binop, rhsrhs, lhs, Side::Rhs)
|
||||
},
|
||||
(_, &ExprKind::Lit(ref lit)) if Self::check_lit(lit, 1) => {
|
||||
(_, ExprKind::Lit(lit)) if Self::check_lit(lit, 1) => {
|
||||
Self::generate_recommendation(cx, binop, rhslhs, lhs, Side::Rhs)
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
},
|
||||
// case where `x + 1 <= ...` or `1 + x <= ...`
|
||||
(BinOpKind::Le, &ExprKind::Binary(ref lhskind, ref lhslhs, ref lhsrhs), _)
|
||||
if lhskind.node == BinOpKind::Add =>
|
||||
{
|
||||
(BinOpKind::Le, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) if lhskind.node == BinOpKind::Add => {
|
||||
match (&lhslhs.kind, &lhsrhs.kind) {
|
||||
// `1 + x` and `x + 1`
|
||||
(&ExprKind::Lit(ref lit), _) if Self::check_lit(lit, 1) => {
|
||||
(ExprKind::Lit(lit), _) if Self::check_lit(lit, 1) => {
|
||||
Self::generate_recommendation(cx, binop, lhsrhs, rhs, Side::Lhs)
|
||||
},
|
||||
(_, &ExprKind::Lit(ref lit)) if Self::check_lit(lit, 1) => {
|
||||
(_, ExprKind::Lit(lit)) if Self::check_lit(lit, 1) => {
|
||||
Self::generate_recommendation(cx, binop, lhslhs, rhs, Side::Lhs)
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
},
|
||||
// case where `... >= y - 1` or `... >= -1 + y`
|
||||
(BinOpKind::Le, _, &ExprKind::Binary(ref rhskind, ref rhslhs, ref rhsrhs)) => {
|
||||
(BinOpKind::Le, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) => {
|
||||
match (rhskind.node, &rhslhs.kind, &rhsrhs.kind) {
|
||||
// `-1 + y`
|
||||
(BinOpKind::Add, &ExprKind::Lit(ref lit), _) if Self::check_lit(lit, -1) => {
|
||||
(BinOpKind::Add, ExprKind::Lit(lit), _) if Self::check_lit(lit, -1) => {
|
||||
Self::generate_recommendation(cx, binop, rhsrhs, lhs, Side::Rhs)
|
||||
},
|
||||
// `y - 1`
|
||||
(BinOpKind::Sub, _, &ExprKind::Lit(ref lit)) if Self::check_lit(lit, 1) => {
|
||||
(BinOpKind::Sub, _, ExprKind::Lit(lit)) if Self::check_lit(lit, 1) => {
|
||||
Self::generate_recommendation(cx, binop, rhslhs, lhs, Side::Rhs)
|
||||
},
|
||||
_ => None,
|
||||
|
|
|
@ -366,8 +366,7 @@ fn check_for_is_empty<'tcx>(
|
|||
}
|
||||
|
||||
fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>, op: &str, compare_to: u32) {
|
||||
if let (&ExprKind::MethodCall(method_path, receiver, args, _), &ExprKind::Lit(ref lit)) = (&method.kind, &lit.kind)
|
||||
{
|
||||
if let (&ExprKind::MethodCall(method_path, receiver, args, _), ExprKind::Lit(lit)) = (&method.kind, &lit.kind) {
|
||||
// check if we are in an is_empty() method
|
||||
if let Some(name) = get_item_name(cx, method) {
|
||||
if name.as_str() == "is_empty" {
|
||||
|
|
|
@ -36,14 +36,14 @@ declare_clippy_lint! {
|
|||
declare_lint_pass!(NeedlessBorrowedRef => [NEEDLESS_BORROWED_REFERENCE]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
|
||||
fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
|
||||
if pat.span.from_expansion() {
|
||||
fn check_pat(&mut self, cx: &LateContext<'tcx>, ref_pat: &'tcx Pat<'_>) {
|
||||
if ref_pat.span.from_expansion() {
|
||||
// OK, simple enough, lints doesn't check in macro.
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not lint patterns that are part of an OR `|` pattern, the binding mode must match in all arms
|
||||
for (_, node) in cx.tcx.hir().parent_iter(pat.hir_id) {
|
||||
for (_, node) in cx.tcx.hir().parent_iter(ref_pat.hir_id) {
|
||||
let Node::Pat(pat) = node else { break };
|
||||
|
||||
if matches!(pat.kind, PatKind::Or(_)) {
|
||||
|
@ -52,20 +52,20 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
|
|||
}
|
||||
|
||||
// Only lint immutable refs, because `&mut ref T` may be useful.
|
||||
let PatKind::Ref(sub_pat, Mutability::Not) = pat.kind else { return };
|
||||
let PatKind::Ref(pat, Mutability::Not) = ref_pat.kind else { return };
|
||||
|
||||
match sub_pat.kind {
|
||||
match pat.kind {
|
||||
// Check sub_pat got a `ref` keyword (excluding `ref mut`).
|
||||
PatKind::Binding(BindingAnnotation::REF, _, ident, None) => {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
NEEDLESS_BORROWED_REFERENCE,
|
||||
pat.span,
|
||||
ref_pat.span,
|
||||
"this pattern takes a reference on something that is being dereferenced",
|
||||
|diag| {
|
||||
// `&ref ident`
|
||||
// ^^^^^
|
||||
let span = pat.span.until(ident.span);
|
||||
let span = ref_pat.span.until(ident.span);
|
||||
diag.span_suggestion_verbose(
|
||||
span,
|
||||
"try removing the `&ref` part",
|
||||
|
@ -84,41 +84,71 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
|
|||
}),
|
||||
after,
|
||||
) => {
|
||||
let mut suggestions = Vec::new();
|
||||
|
||||
for element_pat in itertools::chain(before, after) {
|
||||
if let PatKind::Binding(BindingAnnotation::REF, _, ident, None) = element_pat.kind {
|
||||
// `&[..., ref ident, ...]`
|
||||
// ^^^^
|
||||
let span = element_pat.span.until(ident.span);
|
||||
suggestions.push((span, String::new()));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if !suggestions.is_empty() {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
NEEDLESS_BORROWED_REFERENCE,
|
||||
pat.span,
|
||||
"dereferencing a slice pattern where every element takes a reference",
|
||||
|diag| {
|
||||
// `&[...]`
|
||||
// ^
|
||||
let span = pat.span.until(sub_pat.span);
|
||||
suggestions.push((span, String::new()));
|
||||
|
||||
diag.multipart_suggestion(
|
||||
"try removing the `&` and `ref` parts",
|
||||
suggestions,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
check_subpatterns(
|
||||
cx,
|
||||
"dereferencing a slice pattern where every element takes a reference",
|
||||
ref_pat,
|
||||
pat,
|
||||
itertools::chain(before, after),
|
||||
);
|
||||
},
|
||||
PatKind::Tuple(subpatterns, _) | PatKind::TupleStruct(_, subpatterns, _) => {
|
||||
check_subpatterns(
|
||||
cx,
|
||||
"dereferencing a tuple pattern where every element takes a reference",
|
||||
ref_pat,
|
||||
pat,
|
||||
subpatterns,
|
||||
);
|
||||
},
|
||||
PatKind::Struct(_, fields, _) => {
|
||||
check_subpatterns(
|
||||
cx,
|
||||
"dereferencing a struct pattern where every field's pattern takes a reference",
|
||||
ref_pat,
|
||||
pat,
|
||||
fields.iter().map(|field| field.pat),
|
||||
);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_subpatterns<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
message: &str,
|
||||
ref_pat: &Pat<'_>,
|
||||
pat: &Pat<'_>,
|
||||
subpatterns: impl IntoIterator<Item = &'tcx Pat<'tcx>>,
|
||||
) {
|
||||
let mut suggestions = Vec::new();
|
||||
|
||||
for subpattern in subpatterns {
|
||||
match subpattern.kind {
|
||||
PatKind::Binding(BindingAnnotation::REF, _, ident, None) => {
|
||||
// `ref ident`
|
||||
// ^^^^
|
||||
let span = subpattern.span.until(ident.span);
|
||||
suggestions.push((span, String::new()));
|
||||
},
|
||||
PatKind::Wild => {},
|
||||
_ => return,
|
||||
}
|
||||
}
|
||||
|
||||
if !suggestions.is_empty() {
|
||||
span_lint_and_then(cx, NEEDLESS_BORROWED_REFERENCE, ref_pat.span, message, |diag| {
|
||||
// `&pat`
|
||||
// ^
|
||||
let span = ref_pat.span.until(pat.span);
|
||||
suggestions.push((span, String::new()));
|
||||
|
||||
diag.multipart_suggestion(
|
||||
"try removing the `&` and `ref` parts",
|
||||
suggestions,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ fn check_use_tree(use_tree: &UseTree, cx: &EarlyContext<'_>, span: Span) {
|
|||
},
|
||||
UseTreeKind::Simple(None, ..) | UseTreeKind::Glob => {},
|
||||
UseTreeKind::Nested(ref nested_use_tree) => {
|
||||
for &(ref use_tree, _) in nested_use_tree {
|
||||
for (use_tree, _) in nested_use_tree {
|
||||
check_use_tree(use_tree, cx, span);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -51,8 +51,8 @@ pub enum Constant {
|
|||
impl PartialEq for Constant {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(&Self::Str(ref ls), &Self::Str(ref rs)) => ls == rs,
|
||||
(&Self::Binary(ref l), &Self::Binary(ref r)) => l == r,
|
||||
(Self::Str(ls), Self::Str(rs)) => ls == rs,
|
||||
(Self::Binary(l), Self::Binary(r)) => l == r,
|
||||
(&Self::Char(l), &Self::Char(r)) => l == r,
|
||||
(&Self::Int(l), &Self::Int(r)) => l == r,
|
||||
(&Self::F64(l), &Self::F64(r)) => {
|
||||
|
@ -69,8 +69,8 @@ impl PartialEq for Constant {
|
|||
},
|
||||
(&Self::Bool(l), &Self::Bool(r)) => l == r,
|
||||
(&Self::Vec(ref l), &Self::Vec(ref r)) | (&Self::Tuple(ref l), &Self::Tuple(ref r)) => l == r,
|
||||
(&Self::Repeat(ref lv, ref ls), &Self::Repeat(ref rv, ref rs)) => ls == rs && lv == rv,
|
||||
(&Self::Ref(ref lb), &Self::Ref(ref rb)) => *lb == *rb,
|
||||
(Self::Repeat(lv, ls), Self::Repeat(rv, rs)) => ls == rs && lv == rv,
|
||||
(Self::Ref(lb), Self::Ref(rb)) => *lb == *rb,
|
||||
// TODO: are there inter-type equalities?
|
||||
_ => false,
|
||||
}
|
||||
|
@ -126,8 +126,8 @@ impl Hash for Constant {
|
|||
impl Constant {
|
||||
pub fn partial_cmp(tcx: TyCtxt<'_>, cmp_type: Ty<'_>, left: &Self, right: &Self) -> Option<Ordering> {
|
||||
match (left, right) {
|
||||
(&Self::Str(ref ls), &Self::Str(ref rs)) => Some(ls.cmp(rs)),
|
||||
(&Self::Char(ref l), &Self::Char(ref r)) => Some(l.cmp(r)),
|
||||
(Self::Str(ls), Self::Str(rs)) => Some(ls.cmp(rs)),
|
||||
(Self::Char(l), Self::Char(r)) => Some(l.cmp(r)),
|
||||
(&Self::Int(l), &Self::Int(r)) => match *cmp_type.kind() {
|
||||
ty::Int(int_ty) => Some(sext(tcx, l, int_ty).cmp(&sext(tcx, r, int_ty))),
|
||||
ty::Uint(_) => Some(l.cmp(&r)),
|
||||
|
@ -135,8 +135,8 @@ impl Constant {
|
|||
},
|
||||
(&Self::F64(l), &Self::F64(r)) => l.partial_cmp(&r),
|
||||
(&Self::F32(l), &Self::F32(r)) => l.partial_cmp(&r),
|
||||
(&Self::Bool(ref l), &Self::Bool(ref r)) => Some(l.cmp(r)),
|
||||
(&Self::Tuple(ref l), &Self::Tuple(ref r)) if l.len() == r.len() => match *cmp_type.kind() {
|
||||
(Self::Bool(l), Self::Bool(r)) => Some(l.cmp(r)),
|
||||
(Self::Tuple(l), Self::Tuple(r)) if l.len() == r.len() => match *cmp_type.kind() {
|
||||
ty::Tuple(tys) if tys.len() == l.len() => l
|
||||
.iter()
|
||||
.zip(r)
|
||||
|
@ -146,7 +146,7 @@ impl Constant {
|
|||
.unwrap_or_else(|| Some(l.len().cmp(&r.len()))),
|
||||
_ => None,
|
||||
},
|
||||
(&Self::Vec(ref l), &Self::Vec(ref r)) => {
|
||||
(Self::Vec(l), Self::Vec(r)) => {
|
||||
let (ty::Array(cmp_type, _) | ty::Slice(cmp_type)) = *cmp_type.kind() else {
|
||||
return None
|
||||
};
|
||||
|
@ -155,7 +155,7 @@ impl Constant {
|
|||
.find(|r| r.map_or(true, |o| o != Ordering::Equal))
|
||||
.unwrap_or_else(|| Some(l.len().cmp(&r.len())))
|
||||
},
|
||||
(&Self::Repeat(ref lv, ref ls), &Self::Repeat(ref rv, ref rs)) => {
|
||||
(Self::Repeat(lv, ls), Self::Repeat(rv, rs)) => {
|
||||
match Self::partial_cmp(
|
||||
tcx,
|
||||
match *cmp_type.kind() {
|
||||
|
@ -169,7 +169,7 @@ impl Constant {
|
|||
x => x,
|
||||
}
|
||||
},
|
||||
(&Self::Ref(ref lb), &Self::Ref(ref rb)) => Self::partial_cmp(
|
||||
(Self::Ref(lb), Self::Ref(rb)) => Self::partial_cmp(
|
||||
tcx,
|
||||
match *cmp_type.kind() {
|
||||
ty::Ref(_, ty, _) => ty,
|
||||
|
|
|
@ -266,7 +266,7 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
(&ExprKind::Let(l), &ExprKind::Let(r)) => {
|
||||
self.eq_pat(l.pat, r.pat) && both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) && self.eq_expr(l.init, r.init)
|
||||
},
|
||||
(&ExprKind::Lit(ref l), &ExprKind::Lit(ref r)) => l.node == r.node,
|
||||
(ExprKind::Lit(l), ExprKind::Lit(r)) => l.node == r.node,
|
||||
(&ExprKind::Loop(lb, ref ll, ref lls, _), &ExprKind::Loop(rb, ref rl, ref rls, _)) => {
|
||||
lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.name == r.ident.name)
|
||||
},
|
||||
|
@ -291,8 +291,8 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
(&ExprKind::Repeat(le, ll), &ExprKind::Repeat(re, rl)) => {
|
||||
self.eq_expr(le, re) && self.eq_array_length(ll, rl)
|
||||
},
|
||||
(&ExprKind::Ret(ref l), &ExprKind::Ret(ref r)) => both(l, r, |l, r| self.eq_expr(l, r)),
|
||||
(&ExprKind::Path(ref l), &ExprKind::Path(ref r)) => self.eq_qpath(l, r),
|
||||
(ExprKind::Ret(l), ExprKind::Ret(r)) => both(l, r, |l, r| self.eq_expr(l, r)),
|
||||
(ExprKind::Path(l), ExprKind::Path(r)) => self.eq_qpath(l, r),
|
||||
(&ExprKind::Struct(l_path, lf, ref lo), &ExprKind::Struct(r_path, rf, ref ro)) => {
|
||||
self.eq_qpath(l_path, r_path)
|
||||
&& both(lo, ro, |l, r| self.eq_expr(l, r))
|
||||
|
@ -362,7 +362,7 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
}
|
||||
eq
|
||||
},
|
||||
(&PatKind::Path(ref l), &PatKind::Path(ref r)) => self.eq_qpath(l, r),
|
||||
(PatKind::Path(l), PatKind::Path(r)) => self.eq_qpath(l, r),
|
||||
(&PatKind::Lit(l), &PatKind::Lit(r)) => self.eq_expr(l, r),
|
||||
(&PatKind::Tuple(l, ls), &PatKind::Tuple(r, rs)) => ls == rs && over(l, r, |l, r| self.eq_pat(l, r)),
|
||||
(&PatKind::Range(ref ls, ref le, li), &PatKind::Range(ref rs, ref re, ri)) => {
|
||||
|
@ -429,13 +429,11 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
match (&left.kind, &right.kind) {
|
||||
(&TyKind::Slice(l_vec), &TyKind::Slice(r_vec)) => self.eq_ty(l_vec, r_vec),
|
||||
(&TyKind::Array(lt, ll), &TyKind::Array(rt, rl)) => self.eq_ty(lt, rt) && self.eq_array_length(ll, rl),
|
||||
(&TyKind::Ptr(ref l_mut), &TyKind::Ptr(ref r_mut)) => {
|
||||
l_mut.mutbl == r_mut.mutbl && self.eq_ty(l_mut.ty, r_mut.ty)
|
||||
},
|
||||
(&TyKind::Rptr(_, ref l_rmut), &TyKind::Rptr(_, ref r_rmut)) => {
|
||||
(TyKind::Ptr(l_mut), TyKind::Ptr(r_mut)) => l_mut.mutbl == r_mut.mutbl && self.eq_ty(l_mut.ty, r_mut.ty),
|
||||
(TyKind::Rptr(_, l_rmut), TyKind::Rptr(_, r_rmut)) => {
|
||||
l_rmut.mutbl == r_rmut.mutbl && self.eq_ty(l_rmut.ty, r_rmut.ty)
|
||||
},
|
||||
(&TyKind::Path(ref l), &TyKind::Path(ref r)) => self.eq_qpath(l, r),
|
||||
(TyKind::Path(l), TyKind::Path(r)) => self.eq_qpath(l, r),
|
||||
(&TyKind::Tup(l), &TyKind::Tup(r)) => over(l, r, |l, r| self.eq_ty(l, r)),
|
||||
(&TyKind::Infer, &TyKind::Infer) => true,
|
||||
_ => false,
|
||||
|
|
|
@ -2,7 +2,12 @@
|
|||
|
||||
#![feature(custom_inner_attributes)]
|
||||
#![warn(clippy::match_like_matches_macro)]
|
||||
#![allow(unreachable_patterns, dead_code, clippy::equatable_if_let)]
|
||||
#![allow(
|
||||
unreachable_patterns,
|
||||
dead_code,
|
||||
clippy::equatable_if_let,
|
||||
clippy::needless_borrowed_reference
|
||||
)]
|
||||
|
||||
fn main() {
|
||||
let x = Some(5);
|
||||
|
|
|
@ -2,7 +2,12 @@
|
|||
|
||||
#![feature(custom_inner_attributes)]
|
||||
#![warn(clippy::match_like_matches_macro)]
|
||||
#![allow(unreachable_patterns, dead_code, clippy::equatable_if_let)]
|
||||
#![allow(
|
||||
unreachable_patterns,
|
||||
dead_code,
|
||||
clippy::equatable_if_let,
|
||||
clippy::needless_borrowed_reference
|
||||
)]
|
||||
|
||||
fn main() {
|
||||
let x = Some(5);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: match expression looks like `matches!` macro
|
||||
--> $DIR/match_expr_like_matches_macro.rs:11: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: match expression looks like `matches!` macro
|
||||
--> $DIR/match_expr_like_matches_macro.rs:17:14
|
||||
--> $DIR/match_expr_like_matches_macro.rs:22:14
|
||||
|
|
||||
LL | let _w = match x {
|
||||
| ______________^
|
||||
|
@ -21,7 +21,7 @@ LL | | };
|
|||
| |_____^ help: try this: `matches!(x, Some(_))`
|
||||
|
||||
error: redundant pattern matching, consider using `is_none()`
|
||||
--> $DIR/match_expr_like_matches_macro.rs:23:14
|
||||
--> $DIR/match_expr_like_matches_macro.rs:28:14
|
||||
|
|
||||
LL | let _z = match x {
|
||||
| ______________^
|
||||
|
@ -33,7 +33,7 @@ LL | | };
|
|||
= note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
|
||||
|
||||
error: match expression looks like `matches!` macro
|
||||
--> $DIR/match_expr_like_matches_macro.rs:29:15
|
||||
--> $DIR/match_expr_like_matches_macro.rs:34:15
|
||||
|
|
||||
LL | let _zz = match x {
|
||||
| _______________^
|
||||
|
@ -43,13 +43,13 @@ LL | | };
|
|||
| |_____^ help: try this: `!matches!(x, Some(r) if r == 0)`
|
||||
|
||||
error: if let .. else expression looks like `matches!` macro
|
||||
--> $DIR/match_expr_like_matches_macro.rs:35:16
|
||||
--> $DIR/match_expr_like_matches_macro.rs:40:16
|
||||
|
|
||||
LL | let _zzz = if let Some(5) = x { true } else { false };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `matches!(x, Some(5))`
|
||||
|
||||
error: match expression looks like `matches!` macro
|
||||
--> $DIR/match_expr_like_matches_macro.rs:59:20
|
||||
--> $DIR/match_expr_like_matches_macro.rs:64:20
|
||||
|
|
||||
LL | let _ans = match x {
|
||||
| ____________________^
|
||||
|
@ -60,7 +60,7 @@ LL | | };
|
|||
| |_________^ help: try this: `matches!(x, E::A(_) | E::B(_))`
|
||||
|
||||
error: match expression looks like `matches!` macro
|
||||
--> $DIR/match_expr_like_matches_macro.rs:69:20
|
||||
--> $DIR/match_expr_like_matches_macro.rs:74:20
|
||||
|
|
||||
LL | let _ans = match x {
|
||||
| ____________________^
|
||||
|
@ -73,7 +73,7 @@ LL | | };
|
|||
| |_________^ help: try this: `matches!(x, E::A(_) | E::B(_))`
|
||||
|
||||
error: match expression looks like `matches!` macro
|
||||
--> $DIR/match_expr_like_matches_macro.rs:79:20
|
||||
--> $DIR/match_expr_like_matches_macro.rs:84:20
|
||||
|
|
||||
LL | let _ans = match x {
|
||||
| ____________________^
|
||||
|
@ -84,7 +84,7 @@ LL | | };
|
|||
| |_________^ help: try this: `!matches!(x, E::B(_) | E::C)`
|
||||
|
||||
error: match expression looks like `matches!` macro
|
||||
--> $DIR/match_expr_like_matches_macro.rs:139:18
|
||||
--> $DIR/match_expr_like_matches_macro.rs:144:18
|
||||
|
|
||||
LL | let _z = match &z {
|
||||
| __________________^
|
||||
|
@ -94,7 +94,7 @@ LL | | };
|
|||
| |_________^ help: try this: `matches!(z, Some(3))`
|
||||
|
||||
error: match expression looks like `matches!` macro
|
||||
--> $DIR/match_expr_like_matches_macro.rs:148:18
|
||||
--> $DIR/match_expr_like_matches_macro.rs:153:18
|
||||
|
|
||||
LL | let _z = match &z {
|
||||
| __________________^
|
||||
|
@ -104,7 +104,7 @@ LL | | };
|
|||
| |_________^ help: try this: `matches!(&z, Some(3))`
|
||||
|
||||
error: match expression looks like `matches!` macro
|
||||
--> $DIR/match_expr_like_matches_macro.rs:165:21
|
||||
--> $DIR/match_expr_like_matches_macro.rs:170:21
|
||||
|
|
||||
LL | let _ = match &z {
|
||||
| _____________________^
|
||||
|
@ -114,7 +114,7 @@ LL | | };
|
|||
| |_____________^ help: try this: `matches!(&z, AnEnum::X)`
|
||||
|
||||
error: match expression looks like `matches!` macro
|
||||
--> $DIR/match_expr_like_matches_macro.rs:179:20
|
||||
--> $DIR/match_expr_like_matches_macro.rs:184:20
|
||||
|
|
||||
LL | let _res = match &val {
|
||||
| ____________________^
|
||||
|
@ -124,7 +124,7 @@ LL | | };
|
|||
| |_________^ help: try this: `matches!(&val, &Some(ref _a))`
|
||||
|
||||
error: match expression looks like `matches!` macro
|
||||
--> $DIR/match_expr_like_matches_macro.rs:191:20
|
||||
--> $DIR/match_expr_like_matches_macro.rs:196:20
|
||||
|
|
||||
LL | let _res = match &val {
|
||||
| ____________________^
|
||||
|
@ -134,7 +134,7 @@ LL | | };
|
|||
| |_________^ help: try this: `matches!(&val, &Some(ref _a))`
|
||||
|
||||
error: match expression looks like `matches!` macro
|
||||
--> $DIR/match_expr_like_matches_macro.rs:251:14
|
||||
--> $DIR/match_expr_like_matches_macro.rs:256:14
|
||||
|
|
||||
LL | let _y = match Some(5) {
|
||||
| ______________^
|
||||
|
|
|
@ -1,11 +1,32 @@
|
|||
// run-rustfix
|
||||
|
||||
#![warn(clippy::needless_borrowed_reference)]
|
||||
#![allow(unused, clippy::needless_borrow)]
|
||||
#![allow(
|
||||
unused,
|
||||
irrefutable_let_patterns,
|
||||
non_shorthand_field_patterns,
|
||||
clippy::needless_borrow
|
||||
)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
fn should_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>) {
|
||||
struct Struct {
|
||||
a: usize,
|
||||
b: usize,
|
||||
c: usize,
|
||||
}
|
||||
|
||||
struct TupleStruct(u8, u8, u8);
|
||||
|
||||
fn should_lint(
|
||||
array: [u8; 4],
|
||||
slice: &[u8],
|
||||
slice_of_refs: &[&u8],
|
||||
vec: Vec<u8>,
|
||||
tuple: (u8, u8, u8),
|
||||
tuple_struct: TupleStruct,
|
||||
s: Struct,
|
||||
) {
|
||||
let mut v = Vec::<String>::new();
|
||||
let _ = v.iter_mut().filter(|a| a.is_empty());
|
||||
|
||||
|
@ -24,16 +45,54 @@ fn should_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>
|
|||
if let [a, b, ..] = slice {}
|
||||
if let [a, .., b] = slice {}
|
||||
if let [.., a, b] = slice {}
|
||||
|
||||
if let [a, _] = slice {}
|
||||
|
||||
if let (a, b, c) = &tuple {}
|
||||
if let (a, _, c) = &tuple {}
|
||||
if let (a, ..) = &tuple {}
|
||||
|
||||
if let TupleStruct(a, ..) = &tuple_struct {}
|
||||
|
||||
if let Struct {
|
||||
a,
|
||||
b: b,
|
||||
c: renamed,
|
||||
} = &s
|
||||
{}
|
||||
|
||||
if let Struct { a, b: _, .. } = &s {}
|
||||
}
|
||||
|
||||
fn should_not_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>) {
|
||||
fn should_not_lint(
|
||||
array: [u8; 4],
|
||||
slice: &[u8],
|
||||
slice_of_refs: &[&u8],
|
||||
vec: Vec<u8>,
|
||||
tuple: (u8, u8, u8),
|
||||
tuple_struct: TupleStruct,
|
||||
s: Struct,
|
||||
) {
|
||||
if let [ref a] = slice {}
|
||||
if let &[ref a, b] = slice {}
|
||||
if let &[ref a, .., b] = slice {}
|
||||
|
||||
if let &(ref a, b, ..) = &tuple {}
|
||||
if let &TupleStruct(ref a, b, ..) = &tuple_struct {}
|
||||
if let &Struct { ref a, b, .. } = &s {}
|
||||
|
||||
// must not be removed as variables must be bound consistently across | patterns
|
||||
if let (&[ref a], _) | ([], ref a) = (slice_of_refs, &1u8) {}
|
||||
|
||||
// the `&`s here technically could be removed, but it'd be noisy and without a `ref` doesn't match
|
||||
// the lint name
|
||||
if let &[] = slice {}
|
||||
if let &[_] = slice {}
|
||||
if let &[..] = slice {}
|
||||
if let &(..) = &tuple {}
|
||||
if let &TupleStruct(..) = &tuple_struct {}
|
||||
if let &Struct { .. } = &s {}
|
||||
|
||||
let mut var2 = 5;
|
||||
let thingy2 = Some(&mut var2);
|
||||
if let Some(&mut ref mut v) = thingy2 {
|
||||
|
@ -59,6 +118,6 @@ fn foo(a: &Animal, b: &Animal) {
|
|||
// lifetime mismatch error if there is no '&ref' before `feature(nll)` stabilization in 1.63
|
||||
(&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (),
|
||||
// ^ and ^ should **not** be linted
|
||||
(&Animal::Dog(ref a), &Animal::Dog(_)) => (), // ^ should **not** be linted
|
||||
(Animal::Dog(a), &Animal::Dog(_)) => (),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,32 @@
|
|||
// run-rustfix
|
||||
|
||||
#![warn(clippy::needless_borrowed_reference)]
|
||||
#![allow(unused, clippy::needless_borrow)]
|
||||
#![allow(
|
||||
unused,
|
||||
irrefutable_let_patterns,
|
||||
non_shorthand_field_patterns,
|
||||
clippy::needless_borrow
|
||||
)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
fn should_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>) {
|
||||
struct Struct {
|
||||
a: usize,
|
||||
b: usize,
|
||||
c: usize,
|
||||
}
|
||||
|
||||
struct TupleStruct(u8, u8, u8);
|
||||
|
||||
fn should_lint(
|
||||
array: [u8; 4],
|
||||
slice: &[u8],
|
||||
slice_of_refs: &[&u8],
|
||||
vec: Vec<u8>,
|
||||
tuple: (u8, u8, u8),
|
||||
tuple_struct: TupleStruct,
|
||||
s: Struct,
|
||||
) {
|
||||
let mut v = Vec::<String>::new();
|
||||
let _ = v.iter_mut().filter(|&ref a| a.is_empty());
|
||||
|
||||
|
@ -24,16 +45,54 @@ fn should_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>
|
|||
if let &[ref a, ref b, ..] = slice {}
|
||||
if let &[ref a, .., ref b] = slice {}
|
||||
if let &[.., ref a, ref b] = slice {}
|
||||
|
||||
if let &[ref a, _] = slice {}
|
||||
|
||||
if let &(ref a, ref b, ref c) = &tuple {}
|
||||
if let &(ref a, _, ref c) = &tuple {}
|
||||
if let &(ref a, ..) = &tuple {}
|
||||
|
||||
if let &TupleStruct(ref a, ..) = &tuple_struct {}
|
||||
|
||||
if let &Struct {
|
||||
ref a,
|
||||
b: ref b,
|
||||
c: ref renamed,
|
||||
} = &s
|
||||
{}
|
||||
|
||||
if let &Struct { ref a, b: _, .. } = &s {}
|
||||
}
|
||||
|
||||
fn should_not_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>) {
|
||||
fn should_not_lint(
|
||||
array: [u8; 4],
|
||||
slice: &[u8],
|
||||
slice_of_refs: &[&u8],
|
||||
vec: Vec<u8>,
|
||||
tuple: (u8, u8, u8),
|
||||
tuple_struct: TupleStruct,
|
||||
s: Struct,
|
||||
) {
|
||||
if let [ref a] = slice {}
|
||||
if let &[ref a, b] = slice {}
|
||||
if let &[ref a, .., b] = slice {}
|
||||
|
||||
if let &(ref a, b, ..) = &tuple {}
|
||||
if let &TupleStruct(ref a, b, ..) = &tuple_struct {}
|
||||
if let &Struct { ref a, b, .. } = &s {}
|
||||
|
||||
// must not be removed as variables must be bound consistently across | patterns
|
||||
if let (&[ref a], _) | ([], ref a) = (slice_of_refs, &1u8) {}
|
||||
|
||||
// the `&`s here technically could be removed, but it'd be noisy and without a `ref` doesn't match
|
||||
// the lint name
|
||||
if let &[] = slice {}
|
||||
if let &[_] = slice {}
|
||||
if let &[..] = slice {}
|
||||
if let &(..) = &tuple {}
|
||||
if let &TupleStruct(..) = &tuple_struct {}
|
||||
if let &Struct { .. } = &s {}
|
||||
|
||||
let mut var2 = 5;
|
||||
let thingy2 = Some(&mut var2);
|
||||
if let Some(&mut ref mut v) = thingy2 {
|
||||
|
@ -59,6 +118,6 @@ fn foo(a: &Animal, b: &Animal) {
|
|||
// lifetime mismatch error if there is no '&ref' before `feature(nll)` stabilization in 1.63
|
||||
(&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (),
|
||||
// ^ and ^ should **not** be linted
|
||||
(&Animal::Dog(ref a), &Animal::Dog(_)) => (), // ^ should **not** be linted
|
||||
(Animal::Dog(a), &Animal::Dog(_)) => (),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: this pattern takes a reference on something that is being dereferenced
|
||||
--> $DIR/needless_borrowed_ref.rs:10:34
|
||||
--> $DIR/needless_borrowed_ref.rs:31:34
|
||||
|
|
||||
LL | let _ = v.iter_mut().filter(|&ref a| a.is_empty());
|
||||
| ^^^^^^
|
||||
|
@ -12,7 +12,7 @@ LL + let _ = v.iter_mut().filter(|a| a.is_empty());
|
|||
|
|
||||
|
||||
error: this pattern takes a reference on something that is being dereferenced
|
||||
--> $DIR/needless_borrowed_ref.rs:14:17
|
||||
--> $DIR/needless_borrowed_ref.rs:35:17
|
||||
|
|
||||
LL | if let Some(&ref v) = thingy {}
|
||||
| ^^^^^^
|
||||
|
@ -24,7 +24,7 @@ LL + if let Some(v) = thingy {}
|
|||
|
|
||||
|
||||
error: this pattern takes a reference on something that is being dereferenced
|
||||
--> $DIR/needless_borrowed_ref.rs:16:14
|
||||
--> $DIR/needless_borrowed_ref.rs:37:14
|
||||
|
|
||||
LL | if let &[&ref a, ref b] = slice_of_refs {}
|
||||
| ^^^^^^
|
||||
|
@ -36,7 +36,7 @@ LL + if let &[a, ref b] = slice_of_refs {}
|
|||
|
|
||||
|
||||
error: dereferencing a slice pattern where every element takes a reference
|
||||
--> $DIR/needless_borrowed_ref.rs:18:9
|
||||
--> $DIR/needless_borrowed_ref.rs:39:9
|
||||
|
|
||||
LL | let &[ref a, ..] = &array;
|
||||
| ^^^^^^^^^^^^
|
||||
|
@ -48,7 +48,7 @@ LL + let [a, ..] = &array;
|
|||
|
|
||||
|
||||
error: dereferencing a slice pattern where every element takes a reference
|
||||
--> $DIR/needless_borrowed_ref.rs:19:9
|
||||
--> $DIR/needless_borrowed_ref.rs:40:9
|
||||
|
|
||||
LL | let &[ref a, ref b, ..] = &array;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -60,7 +60,7 @@ LL + let [a, b, ..] = &array;
|
|||
|
|
||||
|
||||
error: dereferencing a slice pattern where every element takes a reference
|
||||
--> $DIR/needless_borrowed_ref.rs:21:12
|
||||
--> $DIR/needless_borrowed_ref.rs:42:12
|
||||
|
|
||||
LL | if let &[ref a, ref b] = slice {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
@ -72,7 +72,7 @@ LL + if let [a, b] = slice {}
|
|||
|
|
||||
|
||||
error: dereferencing a slice pattern where every element takes a reference
|
||||
--> $DIR/needless_borrowed_ref.rs:22:12
|
||||
--> $DIR/needless_borrowed_ref.rs:43:12
|
||||
|
|
||||
LL | if let &[ref a, ref b] = &vec[..] {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
@ -84,7 +84,7 @@ LL + if let [a, b] = &vec[..] {}
|
|||
|
|
||||
|
||||
error: dereferencing a slice pattern where every element takes a reference
|
||||
--> $DIR/needless_borrowed_ref.rs:24:12
|
||||
--> $DIR/needless_borrowed_ref.rs:45:12
|
||||
|
|
||||
LL | if let &[ref a, ref b, ..] = slice {}
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -96,7 +96,7 @@ LL + if let [a, b, ..] = slice {}
|
|||
|
|
||||
|
||||
error: dereferencing a slice pattern where every element takes a reference
|
||||
--> $DIR/needless_borrowed_ref.rs:25:12
|
||||
--> $DIR/needless_borrowed_ref.rs:46:12
|
||||
|
|
||||
LL | if let &[ref a, .., ref b] = slice {}
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -108,7 +108,7 @@ LL + if let [a, .., b] = slice {}
|
|||
|
|
||||
|
||||
error: dereferencing a slice pattern where every element takes a reference
|
||||
--> $DIR/needless_borrowed_ref.rs:26:12
|
||||
--> $DIR/needless_borrowed_ref.rs:47:12
|
||||
|
|
||||
LL | if let &[.., ref a, ref b] = slice {}
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -119,5 +119,96 @@ LL - if let &[.., ref a, ref b] = slice {}
|
|||
LL + if let [.., a, b] = slice {}
|
||||
|
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
error: dereferencing a slice pattern where every element takes a reference
|
||||
--> $DIR/needless_borrowed_ref.rs:49:12
|
||||
|
|
||||
LL | if let &[ref a, _] = slice {}
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
help: try removing the `&` and `ref` parts
|
||||
|
|
||||
LL - if let &[ref a, _] = slice {}
|
||||
LL + if let [a, _] = slice {}
|
||||
|
|
||||
|
||||
error: dereferencing a tuple pattern where every element takes a reference
|
||||
--> $DIR/needless_borrowed_ref.rs:51:12
|
||||
|
|
||||
LL | if let &(ref a, ref b, ref c) = &tuple {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: try removing the `&` and `ref` parts
|
||||
|
|
||||
LL - if let &(ref a, ref b, ref c) = &tuple {}
|
||||
LL + if let (a, b, c) = &tuple {}
|
||||
|
|
||||
|
||||
error: dereferencing a tuple pattern where every element takes a reference
|
||||
--> $DIR/needless_borrowed_ref.rs:52:12
|
||||
|
|
||||
LL | if let &(ref a, _, ref c) = &tuple {}
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: try removing the `&` and `ref` parts
|
||||
|
|
||||
LL - if let &(ref a, _, ref c) = &tuple {}
|
||||
LL + if let (a, _, c) = &tuple {}
|
||||
|
|
||||
|
||||
error: dereferencing a tuple pattern where every element takes a reference
|
||||
--> $DIR/needless_borrowed_ref.rs:53:12
|
||||
|
|
||||
LL | if let &(ref a, ..) = &tuple {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
help: try removing the `&` and `ref` parts
|
||||
|
|
||||
LL - if let &(ref a, ..) = &tuple {}
|
||||
LL + if let (a, ..) = &tuple {}
|
||||
|
|
||||
|
||||
error: dereferencing a tuple pattern where every element takes a reference
|
||||
--> $DIR/needless_borrowed_ref.rs:55:12
|
||||
|
|
||||
LL | if let &TupleStruct(ref a, ..) = &tuple_struct {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: try removing the `&` and `ref` parts
|
||||
|
|
||||
LL - if let &TupleStruct(ref a, ..) = &tuple_struct {}
|
||||
LL + if let TupleStruct(a, ..) = &tuple_struct {}
|
||||
|
|
||||
|
||||
error: dereferencing a struct pattern where every field's pattern takes a reference
|
||||
--> $DIR/needless_borrowed_ref.rs:57:12
|
||||
|
|
||||
LL | if let &Struct {
|
||||
| ____________^
|
||||
LL | | ref a,
|
||||
LL | | b: ref b,
|
||||
LL | | c: ref renamed,
|
||||
LL | | } = &s
|
||||
| |_____^
|
||||
|
|
||||
help: try removing the `&` and `ref` parts
|
||||
|
|
||||
LL ~ if let Struct {
|
||||
LL ~ a,
|
||||
LL ~ b: b,
|
||||
LL ~ c: renamed,
|
||||
|
|
||||
|
||||
error: dereferencing a struct pattern where every field's pattern takes a reference
|
||||
--> $DIR/needless_borrowed_ref.rs:64:12
|
||||
|
|
||||
LL | if let &Struct { ref a, b: _, .. } = &s {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: try removing the `&` and `ref` parts
|
||||
|
|
||||
LL - if let &Struct { ref a, b: _, .. } = &s {}
|
||||
LL + if let Struct { a, b: _, .. } = &s {}
|
||||
|
|
||||
|
||||
error: aborting due to 17 previous errors
|
||||
|
||||
|
|
Loading…
Reference in a new issue