diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 22942d9fb0c..4f0a533592c 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -2150,18 +2150,19 @@ fn lint_clone_on_ref_ptr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir:: return; }; + let snippet = if in_macro(arg.span) { + snippet_with_macro_callsite(cx, arg.span, "_") + } else { + snippet(cx, arg.span, "_") + }; + span_lint_and_sugg( cx, CLONE_ON_REF_PTR, expr.span, "using `.clone()` on a ref-counted pointer", "try this", - format!( - "{}::<{}>::clone(&{})", - caller_type, - subst.type_at(0), - snippet(cx, arg.span, "_") - ), + format!("{}::<{}>::clone(&{})", caller_type, subst.type_at(0), snippet), Applicability::Unspecified, // Sometimes unnecessary ::<_> after Rc/Arc/Weak ); } diff --git a/tests/ui/unnecessary_clone.rs b/tests/ui/unnecessary_clone.rs index 2c9d4d39e6c..e785ac02feb 100644 --- a/tests/ui/unnecessary_clone.rs +++ b/tests/ui/unnecessary_clone.rs @@ -90,3 +90,21 @@ mod many_derefs { let _ = &encoded.clone(); } } + +mod issue2076 { + use std::rc::Rc; + + macro_rules! try_opt { + ($expr: expr) => { + match $expr { + Some(value) => value, + None => return None, + } + }; + } + + fn func() -> Option> { + let rc = Rc::new(42); + Some(try_opt!(Some(rc)).clone()) + } +} diff --git a/tests/ui/unnecessary_clone.stderr b/tests/ui/unnecessary_clone.stderr index 113fab69009..5ffa6c4fd06 100644 --- a/tests/ui/unnecessary_clone.stderr +++ b/tests/ui/unnecessary_clone.stderr @@ -96,5 +96,11 @@ help: or try being explicit if you are sure, that you want to clone a reference LL | let _ = &<&[u8]>::clone(encoded); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 11 previous errors +error: using `.clone()` on a ref-counted pointer + --> $DIR/unnecessary_clone.rs:108:14 + | +LL | Some(try_opt!(Some(rc)).clone()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `Rc::::clone(&try_opt!(Some(rc)))` + +error: aborting due to 12 previous errors