about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs17
-rw-r--r--src/test/ui/suggestions/auxiliary/issue-81839.rs9
-rw-r--r--src/test/ui/suggestions/issue-81839.rs17
-rw-r--r--src/test/ui/suggestions/issue-81839.stderr27
-rw-r--r--src/test/ui/suggestions/match-prev-arm-needing-semi.stderr9
5 files changed, 71 insertions, 8 deletions
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index 7f27325f7f9..f5e9cc1efcc 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -1074,13 +1074,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
         let last_expr_ty = self.node_ty(last_expr.hir_id);
         let needs_box = match (last_expr_ty.kind(), expected_ty.kind()) {
+            (ty::Opaque(last_def_id, _), ty::Opaque(exp_def_id, _))
+                if last_def_id == exp_def_id =>
+            {
+                StatementAsExpression::CorrectType
+            }
             (ty::Opaque(last_def_id, last_bounds), ty::Opaque(exp_def_id, exp_bounds)) => {
                 debug!(
                     "both opaque, likely future {:?} {:?} {:?} {:?}",
                     last_def_id, last_bounds, exp_def_id, exp_bounds
                 );
-                let last_hir_id = self.tcx.hir().local_def_id_to_hir_id(last_def_id.expect_local());
-                let exp_hir_id = self.tcx.hir().local_def_id_to_hir_id(exp_def_id.expect_local());
+
+                let (last_local_id, exp_local_id) =
+                    match (last_def_id.as_local(), exp_def_id.as_local()) {
+                        (Some(last_hir_id), Some(exp_hir_id)) => (last_hir_id, exp_hir_id),
+                        (_, _) => return None,
+                    };
+
+                let last_hir_id = self.tcx.hir().local_def_id_to_hir_id(last_local_id);
+                let exp_hir_id = self.tcx.hir().local_def_id_to_hir_id(exp_local_id);
+
                 match (
                     &self.tcx.hir().expect_item(last_hir_id).kind,
                     &self.tcx.hir().expect_item(exp_hir_id).kind,
diff --git a/src/test/ui/suggestions/auxiliary/issue-81839.rs b/src/test/ui/suggestions/auxiliary/issue-81839.rs
new file mode 100644
index 00000000000..5683c45adf2
--- /dev/null
+++ b/src/test/ui/suggestions/auxiliary/issue-81839.rs
@@ -0,0 +1,9 @@
+// edition:2018
+
+pub struct Test {}
+
+impl Test {
+    pub async fn answer_str(&self, _s: &str) -> Test {
+        Test {}
+    }
+}
diff --git a/src/test/ui/suggestions/issue-81839.rs b/src/test/ui/suggestions/issue-81839.rs
new file mode 100644
index 00000000000..0b9b7aefe73
--- /dev/null
+++ b/src/test/ui/suggestions/issue-81839.rs
@@ -0,0 +1,17 @@
+// aux-build:issue-81839.rs
+// edition:2018
+
+extern crate issue_81839;
+
+async fn test(ans: &str, num: i32, cx: &issue_81839::Test) -> u32 {
+    match num {
+        1 => {
+            cx.answer_str("hi");
+        }
+        _ => cx.answer_str("hi"), //~ `match` arms have incompatible types
+    }
+
+    1
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/issue-81839.stderr b/src/test/ui/suggestions/issue-81839.stderr
new file mode 100644
index 00000000000..1a289d39e44
--- /dev/null
+++ b/src/test/ui/suggestions/issue-81839.stderr
@@ -0,0 +1,27 @@
+error[E0308]: `match` arms have incompatible types
+  --> $DIR/issue-81839.rs:11:14
+   |
+LL | /     match num {
+LL | |         1 => {
+LL | |             cx.answer_str("hi");
+   | |             --------------------
+   | |             |                  |
+   | |             |                  help: consider removing this semicolon
+   | |             this is found to be of type `()`
+LL | |         }
+LL | |         _ => cx.answer_str("hi"),
+   | |              ^^^^^^^^^^^^^^^^^^^ expected `()`, found opaque type
+LL | |     }
+   | |_____- `match` arms have incompatible types
+   | 
+  ::: $DIR/auxiliary/issue-81839.rs:6:49
+   |
+LL |       pub async fn answer_str(&self, _s: &str) -> Test {
+   |                                                   ---- the `Output` of this `async fn`'s found opaque type
+   |
+   = note:     expected type `()`
+           found opaque type `impl Future`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr b/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr
index e9803a78f94..fae0c498b44 100644
--- a/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr
+++ b/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr
@@ -24,13 +24,10 @@ help: consider `await`ing on the `Future`
    |
 LL |         false => async_dummy().await,
    |                               ^^^^^^
-help: consider removing this semicolon and boxing the expressions
-   |
-LL |             Box::new(async_dummy())
-LL |
-LL |         }
-LL |         false => Box::new(async_dummy()),
+help: consider removing this semicolon
    |
+LL |             async_dummy()
+   |                         --
 
 error[E0308]: `match` arms have incompatible types
   --> $DIR/match-prev-arm-needing-semi.rs:39:18