about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-06-15 13:12:13 +0000
committerbors <bors@rust-lang.org>2019-06-15 13:12:13 +0000
commit9f06855064ed06a50c496577b21ca50f92a2e67d (patch)
tree3dd6289174b8eaa528cae5f4a755bab16d4e5bf5
parentdbebcee8d07b77eae3725988879001e6205c6e47 (diff)
parent34c4117f5f28c8eb8dd61600df1611fd29c8b66e (diff)
downloadrust-9f06855064ed06a50c496577b21ca50f92a2e67d.tar.gz
rust-9f06855064ed06a50c496577b21ca50f92a2e67d.zip
Auto merge of #61143 - estebank:issue-61106, r=eddyb
When suggesting borrow, remove useless clones

Fix #61106.
-rw-r--r--src/librustc_typeck/check/demand.rs19
-rw-r--r--src/test/ui/issues/issue-61106.rs6
-rw-r--r--src/test/ui/issues/issue-61106.stderr15
3 files changed, 39 insertions, 1 deletions
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 69a3f090b0a..aff8eba3130 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -379,7 +379,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     }
                 };
                 if self.can_coerce(ref_ty, expected) {
-                    if let Ok(src) = cm.span_to_snippet(sp) {
+                    let mut sugg_sp = sp;
+                    if let hir::ExprKind::MethodCall(segment, _sp, args) = &expr.node {
+                        let clone_trait = self.tcx.lang_items().clone_trait().unwrap();
+                        if let ([arg], Some(true), "clone") = (
+                            &args[..],
+                            self.tables.borrow().type_dependent_def_id(expr.hir_id).map(|did| {
+                                let ai = self.tcx.associated_item(did);
+                                ai.container == ty::TraitContainer(clone_trait)
+                            }),
+                            &segment.ident.as_str()[..],
+                        ) {
+                            // If this expression had a clone call when suggesting borrowing
+                            // we want to suggest removing it because it'd now be unecessary.
+                            sugg_sp = arg.span;
+                        }
+                    }
+                    if let Ok(src) = cm.span_to_snippet(sugg_sp) {
                         let needs_parens = match expr.node {
                             // parenthesize if needed (Issue #46756)
                             hir::ExprKind::Cast(_, _) |
@@ -425,6 +441,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 }
                             }
                         }
+
                         return Some(match mutability {
                             hir::Mutability::MutMutable => (
                                 sp,
diff --git a/src/test/ui/issues/issue-61106.rs b/src/test/ui/issues/issue-61106.rs
new file mode 100644
index 00000000000..308ef1de3cc
--- /dev/null
+++ b/src/test/ui/issues/issue-61106.rs
@@ -0,0 +1,6 @@
+fn main() {
+    let x = String::new();
+    foo(x.clone()); //~ ERROR mismatched types
+}
+
+fn foo(_: &str) {}
diff --git a/src/test/ui/issues/issue-61106.stderr b/src/test/ui/issues/issue-61106.stderr
new file mode 100644
index 00000000000..ca67d514928
--- /dev/null
+++ b/src/test/ui/issues/issue-61106.stderr
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-61106.rs:3:9
+   |
+LL |     foo(x.clone());
+   |         ^^^^^^^^^
+   |         |
+   |         expected &str, found struct `std::string::String`
+   |         help: consider borrowing here: `&x`
+   |
+   = note: expected type `&str`
+              found type `std::string::String`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.