Skip to content

Commit 20e4c74

Browse files
Handle false positive with map_clone
1 parent 660b058 commit 20e4c74

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

clippy_lints/src/methods/map_clone.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,11 @@ pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_
8686
}
8787
}
8888
},
89-
hir::ExprKind::Call(call, [_]) => {
90-
if let hir::ExprKind::Path(qpath) = call.kind {
89+
hir::ExprKind::Call(call, args) => {
90+
if let hir::ExprKind::Path(qpath) = call.kind
91+
&& let [arg] = args
92+
&& ident_eq(name, arg)
93+
{
9194
handle_path(cx, call, &qpath, e, recv);
9295
}
9396
},
@@ -119,6 +122,9 @@ fn handle_path(
119122
&& let args = args.as_slice()
120123
&& let Some(ty) = args.iter().find_map(|generic_arg| generic_arg.as_type())
121124
&& ty.is_ref()
125+
&& let ty::Ref(_, ty, Mutability::Not) = ty.kind()
126+
&& let ty::FnDef(_, lst) = cx.typeck_results().expr_ty(arg).kind()
127+
&& lst.iter().all(|l| l.as_type() == Some(*ty))
122128
{
123129
lint_path(cx, e.span, recv.span, is_copy(cx, ty.peel_refs()));
124130
}

tests/ui/map_clone.fixed

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
clippy::redundant_clone,
77
clippy::redundant_closure,
88
clippy::useless_asref,
9-
clippy::useless_vec
9+
clippy::useless_vec,
10+
clippy::empty_loop
1011
)]
1112

1213
fn main() {
@@ -117,4 +118,17 @@ fn main() {
117118
let y = x.as_ref().map(|x| String::clone(x));
118119
let x: Result<String, ()> = Ok(String::new());
119120
let y = x.as_ref().map(|x| String::clone(x));
121+
122+
// Issue #12271
123+
{
124+
// Don't lint these
125+
let x: Option<&u8> = None;
126+
let y = x.map(|x| String::clone(loop {}));
127+
let x: Option<&u8> = None;
128+
let y = x.map(|x| u8::clone(loop {}));
129+
let x: Vec<&u8> = vec![];
130+
let y = x.into_iter().map(|x| String::clone(loop {}));
131+
let x: Vec<&u8> = vec![];
132+
let y = x.into_iter().map(|x| u8::clone(loop {}));
133+
}
120134
}

tests/ui/map_clone.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
clippy::redundant_clone,
77
clippy::redundant_closure,
88
clippy::useless_asref,
9-
clippy::useless_vec
9+
clippy::useless_vec,
10+
clippy::empty_loop
1011
)]
1112

1213
fn main() {
@@ -117,4 +118,17 @@ fn main() {
117118
let y = x.as_ref().map(|x| String::clone(x));
118119
let x: Result<String, ()> = Ok(String::new());
119120
let y = x.as_ref().map(|x| String::clone(x));
121+
122+
// Issue #12271
123+
{
124+
// Don't lint these
125+
let x: Option<&u8> = None;
126+
let y = x.map(|x| String::clone(loop {}));
127+
let x: Option<&u8> = None;
128+
let y = x.map(|x| u8::clone(loop {}));
129+
let x: Vec<&u8> = vec![];
130+
let y = x.into_iter().map(|x| String::clone(loop {}));
131+
let x: Vec<&u8> = vec![];
132+
let y = x.into_iter().map(|x| u8::clone(loop {}));
133+
}
120134
}

0 commit comments

Comments
 (0)