From da7dd434c8086378a44ed2c379050dbe5c01a5d7 Mon Sep 17 00:00:00 2001
From: Wafarm <qinyy07@gmail.com>
Date: Sun, 18 Aug 2024 10:44:17 +0800
Subject: [PATCH] Fix wrong argument for `get_fn_decl`

---
 compiler/rustc_hir_typeck/src/coercion.rs     |  2 +-
 .../async-fn/recurse-ice-129215.rs            |  9 +++++
 .../async-fn/recurse-ice-129215.stderr        | 34 +++++++++++++++++++
 .../add_semicolon_non_block_closure.rs        |  1 +
 .../add_semicolon_non_block_closure.stderr    |  6 ++--
 5 files changed, 49 insertions(+), 3 deletions(-)
 create mode 100644 tests/ui/async-await/async-fn/recurse-ice-129215.rs
 create mode 100644 tests/ui/async-await/async-fn/recurse-ice-129215.stderr

diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index d53df251a153..9b34c59f1f1b 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -1859,7 +1859,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
         };
 
         // If this is due to an explicit `return`, suggest adding a return type.
-        if let Some((fn_id, fn_decl, can_suggest)) = fcx.get_fn_decl(parent_id)
+        if let Some((fn_id, fn_decl, can_suggest)) = fcx.get_fn_decl(block_or_return_id)
             && !due_to_block
         {
             fcx.suggest_missing_return_type(&mut err, fn_decl, expected, found, can_suggest, fn_id);
diff --git a/tests/ui/async-await/async-fn/recurse-ice-129215.rs b/tests/ui/async-await/async-fn/recurse-ice-129215.rs
new file mode 100644
index 000000000000..06a2d7be9efb
--- /dev/null
+++ b/tests/ui/async-await/async-fn/recurse-ice-129215.rs
@@ -0,0 +1,9 @@
+//@ edition: 2021
+
+async fn a() {
+    //~^ ERROR `()` is not a future
+    //~| ERROR mismatched types
+    a() //~ ERROR `()` is not a future
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/async-fn/recurse-ice-129215.stderr b/tests/ui/async-await/async-fn/recurse-ice-129215.stderr
new file mode 100644
index 000000000000..98c7be2a5a3f
--- /dev/null
+++ b/tests/ui/async-await/async-fn/recurse-ice-129215.stderr
@@ -0,0 +1,34 @@
+error[E0277]: `()` is not a future
+  --> $DIR/recurse-ice-129215.rs:6:5
+   |
+LL |     a()
+   |     ^^^ `()` is not a future
+   |
+   = help: the trait `Future` is not implemented for `()`
+
+error[E0277]: `()` is not a future
+  --> $DIR/recurse-ice-129215.rs:3:1
+   |
+LL | async fn a() {
+   | ^^^^^^^^^^^^ `()` is not a future
+   |
+   = help: the trait `Future` is not implemented for `()`
+
+error[E0308]: mismatched types
+  --> $DIR/recurse-ice-129215.rs:3:14
+   |
+LL |   async fn a() {
+   |  ______________^
+LL | |
+LL | |
+LL | |     a()
+LL | | }
+   | |_^ expected `()`, found `async` fn body
+   |
+   = note:    expected unit type `()`
+           found `async` fn body `{async fn body of a()}`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/closures/add_semicolon_non_block_closure.rs b/tests/ui/closures/add_semicolon_non_block_closure.rs
index 3ae91be60c5a..62c5e343cd34 100644
--- a/tests/ui/closures/add_semicolon_non_block_closure.rs
+++ b/tests/ui/closures/add_semicolon_non_block_closure.rs
@@ -8,4 +8,5 @@ fn main() {
     foo(|| bar())
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider using a semicolon here
+    //~| HELP try adding a return type
 }
diff --git a/tests/ui/closures/add_semicolon_non_block_closure.stderr b/tests/ui/closures/add_semicolon_non_block_closure.stderr
index d095e59c7ebb..7883db8f98ec 100644
--- a/tests/ui/closures/add_semicolon_non_block_closure.stderr
+++ b/tests/ui/closures/add_semicolon_non_block_closure.stderr
@@ -1,8 +1,6 @@
 error[E0308]: mismatched types
   --> $DIR/add_semicolon_non_block_closure.rs:8:12
    |
-LL | fn main() {
-   |          - expected `()` because of default return type
 LL |     foo(|| bar())
    |            ^^^^^ expected `()`, found `i32`
    |
@@ -10,6 +8,10 @@ help: consider using a semicolon here
    |
 LL |     foo(|| { bar(); })
    |            +      +++
+help: try adding a return type
+   |
+LL |     foo(|| -> i32 bar())
+   |            ++++++
 
 error: aborting due to 1 previous error