about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-03 07:37:43 +0000
committerbors <bors@rust-lang.org>2022-08-03 07:37:43 +0000
commit5dc90a1b6d4c52ad19b2812e5a144f13fc2cdbba (patch)
tree5b9705da257dc7b2035ca0915236e2fc36e5bf20
parent05e7d5481b7d405f0ebb04f3c83fb19618871c19 (diff)
parent503c03c5584bb697071f3585953ed6e5b16d2e10 (diff)
downloadrust-5dc90a1b6d4c52ad19b2812e5a144f13fc2cdbba.tar.gz
rust-5dc90a1b6d4c52ad19b2812e5a144f13fc2cdbba.zip
Auto merge of #9282 - macovedj:clone-on-copy-try-precedence, r=flip1995
add paren before '?' when suggesting deref for clone_on_copy

changelog: none

fixes #9277
-rw-r--r--clippy_lints/src/methods/clone_on_copy.rs7
-rw-r--r--tests/ui/clone_on_copy.fixed7
-rw-r--r--tests/ui/clone_on_copy.rs7
-rw-r--r--tests/ui/clone_on_copy.stderr8
4 files changed, 25 insertions, 4 deletions
diff --git a/clippy_lints/src/methods/clone_on_copy.rs b/clippy_lints/src/methods/clone_on_copy.rs
index 0b38a07204e..60e1355f9b9 100644
--- a/clippy_lints/src/methods/clone_on_copy.rs
+++ b/clippy_lints/src/methods/clone_on_copy.rs
@@ -4,7 +4,7 @@ use clippy_utils::source::snippet_with_context;
 use clippy_utils::sugg;
 use clippy_utils::ty::is_copy;
 use rustc_errors::Applicability;
-use rustc_hir::{BindingAnnotation, Expr, ExprKind, MatchSource, Node, PatKind};
+use rustc_hir::{BindingAnnotation, Expr, ExprKind, MatchSource, Node, PatKind, QPath};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, adjustment::Adjust};
 use rustc_span::symbol::{sym, Symbol};
@@ -86,6 +86,11 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symbol,
                 {
                     return;
                 },
+                // ? is a Call, makes sure not to rec *x?, but rather (*x)?
+                ExprKind::Call(hir_callee, _) => matches!(
+                    hir_callee.kind,
+                    ExprKind::Path(QPath::LangItem(rustc_hir::LangItem::TryTraitBranch, _, _))
+                ),
                 ExprKind::MethodCall(_, [self_arg, ..], _) if expr.hir_id == self_arg.hir_id => true,
                 ExprKind::Match(_, _, MatchSource::TryDesugar | MatchSource::AwaitDesugar)
                 | ExprKind::Field(..)
diff --git a/tests/ui/clone_on_copy.fixed b/tests/ui/clone_on_copy.fixed
index dc062762604..72b12227098 100644
--- a/tests/ui/clone_on_copy.fixed
+++ b/tests/ui/clone_on_copy.fixed
@@ -21,7 +21,7 @@ fn is_ascii(ch: char) -> bool {
     ch.is_ascii()
 }
 
-fn clone_on_copy() {
+fn clone_on_copy() -> Option<(i32)> {
     42;
 
     vec![1].clone(); // ok, not a Copy type
@@ -71,4 +71,9 @@ fn clone_on_copy() {
     // Issue #5436
     let mut vec = Vec::new();
     vec.push(42);
+
+    //  Issue #9277
+    let opt: &Option<i32> = &None;
+    let value = (*opt)?; // operator precedence needed (*opt)?
+    None
 }
diff --git a/tests/ui/clone_on_copy.rs b/tests/ui/clone_on_copy.rs
index 8c39d0d55dd..03e210ebad9 100644
--- a/tests/ui/clone_on_copy.rs
+++ b/tests/ui/clone_on_copy.rs
@@ -21,7 +21,7 @@ fn is_ascii(ch: char) -> bool {
     ch.is_ascii()
 }
 
-fn clone_on_copy() {
+fn clone_on_copy() -> Option<(i32)> {
     42.clone();
 
     vec![1].clone(); // ok, not a Copy type
@@ -71,4 +71,9 @@ fn clone_on_copy() {
     // Issue #5436
     let mut vec = Vec::new();
     vec.push(42.clone());
+
+    //  Issue #9277
+    let opt: &Option<i32> = &None;
+    let value = opt.clone()?; // operator precedence needed (*opt)?
+    None
 }
diff --git a/tests/ui/clone_on_copy.stderr b/tests/ui/clone_on_copy.stderr
index 861543d0aa9..42ae227777c 100644
--- a/tests/ui/clone_on_copy.stderr
+++ b/tests/ui/clone_on_copy.stderr
@@ -48,5 +48,11 @@ error: using `clone` on type `i32` which implements the `Copy` trait
 LL |     vec.push(42.clone());
    |              ^^^^^^^^^^ help: try removing the `clone` call: `42`
 
-error: aborting due to 8 previous errors
+error: using `clone` on type `std::option::Option<i32>` which implements the `Copy` trait
+  --> $DIR/clone_on_copy.rs:77:17
+   |
+LL |     let value = opt.clone()?; // operator precedence needed (*opt)?
+   |                 ^^^^^^^^^^^ help: try dereferencing it: `(*opt)`
+
+error: aborting due to 9 previous errors