about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-08-26 12:01:32 +0000
committerbors <bors@rust-lang.org>2020-08-26 12:01:32 +0000
commit894581b872ef8f87074815454f25a262d4e699f4 (patch)
tree4aaa438c190875fbfc971b87cb62b7920f6373c7
parent9ef44799bf096efbda9a7f4e5806d6bc11483e28 (diff)
parente8d33d73dc3f9d0daf9b3affe65a2431f5a3e13a (diff)
downloadrust-894581b872ef8f87074815454f25a262d4e699f4.tar.gz
rust-894581b872ef8f87074815454f25a262d4e699f4.zip
Auto merge of #5946 - mikerite:fix-5729, r=flip1995
Fix `let_and_return` bad suggestion

Add a cast to the suggestion when the return expression has adjustments.
These adjustments are lost when the suggestion is applied.

This is similar to the problem in issue #4437.

Closes #5729

changelog: Fix `let_and_return` bad suggestion
-rw-r--r--clippy_lints/src/returns.rs5
-rw-r--r--tests/ui/let_and_return.rs21
-rw-r--r--tests/ui/let_and_return.stderr16
3 files changed, 40 insertions, 2 deletions
diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs
index 3c5541e64b4..a6e4252a0c8 100644
--- a/clippy_lints/src/returns.rs
+++ b/clippy_lints/src/returns.rs
@@ -99,7 +99,10 @@ impl<'tcx> LateLintPass<'tcx> for Return {
                     |err| {
                         err.span_label(local.span, "unnecessary `let` binding");
 
-                        if let Some(snippet) = snippet_opt(cx, initexpr.span) {
+                        if let Some(mut snippet) = snippet_opt(cx, initexpr.span) {
+                            if !cx.typeck_results().expr_adjustments(&retexpr).is_empty() {
+                                snippet.push_str(" as _");
+                            }
                             err.multipart_suggestion(
                                 "return the expression directly",
                                 vec![
diff --git a/tests/ui/let_and_return.rs b/tests/ui/let_and_return.rs
index 09614b8c1ad..73e550b3df8 100644
--- a/tests/ui/let_and_return.rs
+++ b/tests/ui/let_and_return.rs
@@ -135,4 +135,25 @@ mod no_lint_if_stmt_borrows {
     }
 }
 
+mod issue_5729 {
+    use std::sync::Arc;
+
+    trait Foo {}
+
+    trait FooStorage {
+        fn foo_cloned(&self) -> Arc<dyn Foo>;
+    }
+
+    struct FooStorageImpl<T: Foo> {
+        foo: Arc<T>,
+    }
+
+    impl<T: Foo + 'static> FooStorage for FooStorageImpl<T> {
+        fn foo_cloned(&self) -> Arc<dyn Foo> {
+            let clone = Arc::clone(&self.foo);
+            clone
+        }
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/let_and_return.stderr b/tests/ui/let_and_return.stderr
index eacf948b392..fe878e5f206 100644
--- a/tests/ui/let_and_return.stderr
+++ b/tests/ui/let_and_return.stderr
@@ -27,5 +27,19 @@ LL |
 LL |         5
    |
 
-error: aborting due to 2 previous errors
+error: returning the result of a `let` binding from a block
+  --> $DIR/let_and_return.rs:154:13
+   |
+LL |             let clone = Arc::clone(&self.foo);
+   |             ---------------------------------- unnecessary `let` binding
+LL |             clone
+   |             ^^^^^
+   |
+help: return the expression directly
+   |
+LL |             
+LL |             Arc::clone(&self.foo) as _
+   |
+
+error: aborting due to 3 previous errors