Skip to content

Commit 82841aa

Browse files
Fix suggestion for map_clone on types implementing Copy
1 parent 87ff58d commit 82841aa

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

clippy_lints/src/methods/map_clone.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,15 @@ fn handle_path(
113113
if let Some(path_def_id) = cx.qpath_res(qpath, arg.hir_id).opt_def_id()
114114
&& match_def_path(cx, path_def_id, &paths::CLONE_TRAIT_METHOD)
115115
{
116-
// FIXME: It would be better to infer the type to check if it's copyable or not
117-
// to suggest to use `.copied()` instead of `.cloned()` where applicable.
118-
lint_path(cx, e.span, recv.span);
116+
// The `copied` and `cloned` methods are only available on `&T` and `&mut T` in `Option`
117+
// and `Result`.
118+
if let ty::Adt(_, args) = cx.typeck_results().expr_ty(recv).kind()
119+
&& let args = args.as_slice()
120+
&& let Some(ty) = args.iter().find_map(|generic_arg| generic_arg.as_type())
121+
&& ty.is_ref()
122+
{
123+
lint_path(cx, e.span, recv.span, is_copy(cx, ty.peel_refs()));
124+
}
119125
}
120126
}
121127

@@ -139,17 +145,19 @@ fn lint_needless_cloning(cx: &LateContext<'_>, root: Span, receiver: Span) {
139145
);
140146
}
141147

142-
fn lint_path(cx: &LateContext<'_>, replace: Span, root: Span) {
148+
fn lint_path(cx: &LateContext<'_>, replace: Span, root: Span, is_copy: bool) {
143149
let mut applicability = Applicability::MachineApplicable;
144150

151+
let replacement = if is_copy { "copied" } else { "cloned" };
152+
145153
span_lint_and_sugg(
146154
cx,
147155
MAP_CLONE,
148156
replace,
149157
"you are explicitly cloning with `.map()`",
150-
"consider calling the dedicated `cloned` method",
158+
&format!("consider calling the dedicated `{replacement}` method"),
151159
format!(
152-
"{}.cloned()",
160+
"{}.{replacement}()",
153161
snippet_with_applicability(cx, root, "..", &mut applicability),
154162
),
155163
applicability,

0 commit comments

Comments
 (0)