diff options
| author | ThibsG <Thibs@debian.com> | 2020-08-24 14:01:27 +0200 |
|---|---|---|
| committer | ThibsG <Thibs@debian.com> | 2020-08-24 14:05:49 +0200 |
| commit | 3d820f71fe820c0bb7a1204e28ce549407a937cc (patch) | |
| tree | 6bb5210b1dbb3010298079f8c7d96ae7d1f12503 | |
| parent | 27ae4d303ce9103a104c57088913741ab17f4d36 (diff) | |
| download | rust-3d820f71fe820c0bb7a1204e28ce549407a937cc.tar.gz rust-3d820f71fe820c0bb7a1204e28ce549407a937cc.zip | |
Fix incorrect suggestion when `clone_on_ref_ptr` is triggered in macros
| -rw-r--r-- | clippy_lints/src/methods/mod.rs | 13 | ||||
| -rw-r--r-- | tests/ui/unnecessary_clone.rs | 18 | ||||
| -rw-r--r-- | tests/ui/unnecessary_clone.stderr | 8 |
3 files changed, 32 insertions, 7 deletions
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<Rc<u8>> { + 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::<u8>::clone(&try_opt!(Some(rc)))` + +error: aborting due to 12 previous errors |
