about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-08-25 21:48:19 +0000
committerbors <bors@rust-lang.org>2020-08-25 21:48:19 +0000
commitad7a03cbaa01103fbc26ba19a7f505ddccf5316f (patch)
tree31780f8f979b3ca23de1405c360254179babd99b
parente1911510010d639cadd85b7b0fc4e3c6b5bbf05e (diff)
parent370fc45a0a2af502d43f0e1831def314e0580a92 (diff)
downloadrust-ad7a03cbaa01103fbc26ba19a7f505ddccf5316f.tar.gz
rust-ad7a03cbaa01103fbc26ba19a7f505ddccf5316f.zip
Auto merge of #5951 - ThibsG:FixMacroCloneOnRefPtr2076, r=ebroto
Fix incorrect suggestion when `clone_on_ref_ptr` is triggered in macros

In the lint `clone_on_ref_ptr`, if the `span` is in a macro, don't expand it for suggestion.

Fixes: #2076

changelog: none

r? @ebroto
-rw-r--r--clippy_lints/src/methods/mod.rs9
-rw-r--r--tests/ui/unnecessary_clone.rs18
-rw-r--r--tests/ui/unnecessary_clone.stderr8
3 files changed, 28 insertions, 7 deletions
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index 22942d9fb0c..1ef54d285f6 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -2150,18 +2150,15 @@ fn lint_clone_on_ref_ptr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::
             return;
         };
 
+        let snippet = snippet_with_macro_callsite(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