Skip to content

Commit e90eea7

Browse files
Clean up code in map_clone and useless_asref lints
1 parent 8791a28 commit e90eea7

File tree

2 files changed

+59
-59
lines changed

2 files changed

+59
-59
lines changed

clippy_lints/src/methods/map_clone.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use clippy_utils::ty::{is_copy, is_type_diagnostic_item};
55
use clippy_utils::{is_diag_trait_item, match_def_path, paths, peel_blocks};
66
use rustc_errors::Applicability;
77
use rustc_hir as hir;
8+
use rustc_hir::def_id::DefId;
89
use rustc_lint::LateContext;
910
use rustc_middle::mir::Mutability;
1011
use rustc_middle::ty;
@@ -14,12 +15,22 @@ use rustc_span::{sym, Span};
1415

1516
use super::MAP_CLONE;
1617

18+
fn should_run_lint(cx: &LateContext<'_>, method_id: DefId) -> bool {
19+
if is_diag_trait_item(cx, method_id, sym::Iterator) {
20+
return true;
21+
}
22+
if !cx.tcx.impl_of_method(method_id).map_or(false, |id| {
23+
is_type_diagnostic_item(cx, cx.tcx.type_of(id).instantiate_identity(), sym::Option)
24+
|| is_type_diagnostic_item(cx, cx.tcx.type_of(id).instantiate_identity(), sym::Result)
25+
}) {
26+
return false;
27+
}
28+
return true;
29+
}
30+
1731
pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>, msrv: &Msrv) {
1832
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
19-
&& (cx.tcx.impl_of_method(method_id).map_or(false, |id| {
20-
is_type_diagnostic_item(cx, cx.tcx.type_of(id).instantiate_identity(), sym::Option)
21-
|| is_type_diagnostic_item(cx, cx.tcx.type_of(id).instantiate_identity(), sym::Result)
22-
}) || is_diag_trait_item(cx, method_id, sym::Iterator))
33+
&& should_run_lint(cx, method_id)
2334
{
2435
match arg.kind {
2536
hir::ExprKind::Closure(&hir::Closure { body, .. }) => {

clippy_lints/src/methods/useless_asref.rs

Lines changed: 44 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -91,67 +91,56 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str,
9191
// And that it only has one argument.
9292
&& let [arg] = args
9393
{
94-
match arg.kind {
95-
hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
96-
// If it's a closure, we need to check what is called.
97-
let closure_body = cx.tcx.hir().body(body);
98-
let closure_expr = peel_blocks(closure_body.value);
99-
match closure_expr.kind {
100-
hir::ExprKind::MethodCall(method, obj, [], _) => {
101-
if method.ident.name == sym::clone
102-
&& let Some(fn_id) = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id)
103-
&& let Some(trait_id) = cx.tcx.trait_of_item(fn_id)
104-
// We check it's the `Clone` trait.
105-
&& cx.tcx.lang_items().clone_trait().map_or(false, |id| id == trait_id)
106-
// no autoderefs
107-
&& !cx.typeck_results().expr_adjustments(obj).iter()
108-
.any(|a| matches!(a.kind, Adjust::Deref(Some(..))))
109-
{
110-
lint_as_ref_clone(cx, expr.span.with_hi(parent.span.hi()), recvr, call_name);
111-
}
112-
},
113-
hir::ExprKind::Call(call, [_]) => {
114-
if let hir::ExprKind::Path(qpath) = call.kind {
115-
check_qpath(
116-
cx,
117-
expr.span.with_hi(parent.span.hi()),
118-
recvr,
119-
call_name,
120-
qpath,
121-
call.hir_id,
122-
);
123-
}
124-
},
125-
_ => {},
126-
}
127-
},
128-
hir::ExprKind::Path(qpath) => check_qpath(
129-
cx,
130-
expr.span.with_hi(parent.span.hi()),
131-
recvr,
132-
call_name,
133-
qpath,
134-
arg.hir_id,
135-
),
136-
_ => {},
94+
if is_calling_clone(cx, arg) {
95+
lint_as_ref_clone(cx, expr.span.with_hi(parent.span.hi()), recvr, call_name);
13796
}
13897
}
13998
}
14099
}
141100

142-
fn check_qpath(
143-
cx: &LateContext<'_>,
144-
span: Span,
145-
recvr: &hir::Expr<'_>,
146-
call_name: &str,
147-
qpath: hir::QPath<'_>,
148-
hir_id: hir::HirId,
149-
) {
101+
fn check_qpath(cx: &LateContext<'_>, qpath: hir::QPath<'_>, hir_id: hir::HirId) -> bool {
150102
// We check it's calling the `clone` method of the `Clone` trait.
151-
if let Some(path_def_id) = cx.qpath_res(&qpath, hir_id).opt_def_id()
152-
&& match_def_path(cx, path_def_id, &paths::CLONE_TRAIT_METHOD)
153-
{
154-
lint_as_ref_clone(cx, span, recvr, call_name);
103+
if let Some(path_def_id) = cx.qpath_res(&qpath, hir_id).opt_def_id() {
104+
match_def_path(cx, path_def_id, &paths::CLONE_TRAIT_METHOD)
105+
} else {
106+
false
107+
}
108+
}
109+
110+
fn is_calling_clone(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {
111+
match arg.kind {
112+
hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
113+
// If it's a closure, we need to check what is called.
114+
let closure_body = cx.tcx.hir().body(body);
115+
let closure_expr = peel_blocks(closure_body.value);
116+
match closure_expr.kind {
117+
hir::ExprKind::MethodCall(method, obj, [], _) => {
118+
if method.ident.name == sym::clone
119+
&& let Some(fn_id) = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id)
120+
&& let Some(trait_id) = cx.tcx.trait_of_item(fn_id)
121+
// We check it's the `Clone` trait.
122+
&& cx.tcx.lang_items().clone_trait().map_or(false, |id| id == trait_id)
123+
// no autoderefs
124+
&& !cx.typeck_results().expr_adjustments(obj).iter()
125+
.any(|a| matches!(a.kind, Adjust::Deref(Some(..))))
126+
{
127+
true
128+
} else {
129+
false
130+
}
131+
},
132+
hir::ExprKind::Call(call, [_]) => {
133+
if let hir::ExprKind::Path(qpath) = call.kind {
134+
check_qpath(cx, qpath, call.hir_id)
135+
} else {
136+
false
137+
}
138+
},
139+
_ => false,
140+
}
141+
},
142+
hir::ExprKind::Path(qpath) => check_qpath(cx, qpath, arg.hir_id),
143+
_ => false,
155144
}
156145
}
157146

0 commit comments

Comments
 (0)