about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-10-25 19:51:14 +0200
committerGitHub <noreply@github.com>2023-10-25 19:51:14 +0200
commit585a1222649a5ed2b2eb1b328bee05f6a30cd11d (patch)
treedc5b45abddb178e85d87babd7d6310e29b389ca3
parenta1ab16792b2c425abbdee84956f503aa97c07f43 (diff)
parent23341434bdfdecf882b886146e6a25a9a15f09d9 (diff)
downloadrust-585a1222649a5ed2b2eb1b328bee05f6a30cd11d.tar.gz
rust-585a1222649a5ed2b2eb1b328bee05f6a30cd11d.zip
Rollup merge of #117152 - compiler-errors:no-ret-coercion, r=chenyukang
Fix unwrap suggestion for async fn

Use `body_fn_sig` to get the expected return type of the function instead of `ret_coercion` in `FnCtxt`. This avoids accessing the `ret_coercion` when it's already mutably borrowed (e.g. when checking `return` expressions).

Fixes #117144

r? `@chenyukang`
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs22
-rw-r--r--tests/ui/mismatched_types/async-unwrap-suggestion.rs22
-rw-r--r--tests/ui/mismatched_types/async-unwrap-suggestion.stderr25
3 files changed, 57 insertions, 12 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 13aa6454bc3..e1dbf37743f 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -1747,19 +1747,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
     ) -> bool {
-        let ty::Adt(adt, args) = found.kind() else { return false };
+        let ty::Adt(adt, args) = found.kind() else {
+            return false;
+        };
         let ret_ty_matches = |diagnostic_item| {
-            if let Some(ret_ty) = self
-                    .ret_coercion
-                    .as_ref()
-                    .map(|c| self.resolve_vars_if_possible(c.borrow().expected_ty()))
-                    && let ty::Adt(kind, _) = ret_ty.kind()
-                    && self.tcx.get_diagnostic_item(diagnostic_item) == Some(kind.did())
-                {
-                    true
-                } else {
-                    false
-                }
+            let Some(sig) = self.body_fn_sig() else {
+                return false;
+            };
+            let ty::Adt(kind, _) = sig.output().kind() else {
+                return false;
+            };
+            self.tcx.is_diagnostic_item(diagnostic_item, kind.did())
         };
 
         // don't suggest anything like `Ok(ok_val).unwrap()` , `Some(some_val).unwrap()`,
diff --git a/tests/ui/mismatched_types/async-unwrap-suggestion.rs b/tests/ui/mismatched_types/async-unwrap-suggestion.rs
new file mode 100644
index 00000000000..9698cc29ffd
--- /dev/null
+++ b/tests/ui/mismatched_types/async-unwrap-suggestion.rs
@@ -0,0 +1,22 @@
+// edition: 2021
+
+async fn dont_suggest() -> i32 {
+    if false {
+        return Ok(6);
+        //~^ ERROR mismatched types
+    }
+
+    5
+}
+
+async fn do_suggest() -> i32 {
+    if false {
+        let s = Ok(6);
+        return s;
+        //~^ ERROR mismatched types
+    }
+
+    5
+}
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/async-unwrap-suggestion.stderr b/tests/ui/mismatched_types/async-unwrap-suggestion.stderr
new file mode 100644
index 00000000000..80ca76a4b86
--- /dev/null
+++ b/tests/ui/mismatched_types/async-unwrap-suggestion.stderr
@@ -0,0 +1,25 @@
+error[E0308]: mismatched types
+  --> $DIR/async-unwrap-suggestion.rs:5:16
+   |
+LL |         return Ok(6);
+   |                ^^^^^ expected `i32`, found `Result<{integer}, _>`
+   |
+   = note: expected type `i32`
+              found enum `Result<{integer}, _>`
+
+error[E0308]: mismatched types
+  --> $DIR/async-unwrap-suggestion.rs:15:16
+   |
+LL |         return s;
+   |                ^ expected `i32`, found `Result<{integer}, _>`
+   |
+   = note: expected type `i32`
+              found enum `Result<{integer}, _>`
+help: consider using `Result::expect` to unwrap the `Result<{integer}, _>` value, panicking if the value is a `Result::Err`
+   |
+LL |         return s.expect("REASON");
+   |                 +++++++++++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.