about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-01-27 00:50:31 +0000
committerMichael Goulet <michael@errs.io>2024-01-27 19:39:02 +0000
commit5d8c1780fae725ce02a1c4619809347e55af67eb (patch)
tree14894eeb0f13a4eb46abe6825fb5b4a580d3b071
parent6b4f1c5e782c72a047a23e922decd33e7d462345 (diff)
downloadrust-5d8c1780fae725ce02a1c4619809347e55af67eb.tar.gz
rust-5d8c1780fae725ce02a1c4619809347e55af67eb.zip
Make the coroutine def id of an async closure the child of the closure def id
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs18
-rw-r--r--tests/ui/async-await/async-closures/def-path.rs14
-rw-r--r--tests/ui/async-await/async-closures/def-path.stderr17
3 files changed, 43 insertions, 6 deletions
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index b77102c085c..42ace9bb22f 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -289,12 +289,18 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
                 // we must create two defs.
                 let closure_def = self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span);
                 match closure.coroutine_kind {
-                    Some(coroutine_kind) => self.create_def(
-                        coroutine_kind.closure_id(),
-                        kw::Empty,
-                        DefKind::Closure,
-                        expr.span,
-                    ),
+                    Some(coroutine_kind) => {
+                        self.with_parent(closure_def, |this| {
+                            let coroutine_def = this.create_def(
+                                coroutine_kind.closure_id(),
+                                kw::Empty,
+                                DefKind::Closure,
+                                expr.span,
+                            );
+                            this.with_parent(coroutine_def, |this| visit::walk_expr(this, expr));
+                        });
+                        return;
+                    }
                     None => closure_def,
                 }
             }
diff --git a/tests/ui/async-await/async-closures/def-path.rs b/tests/ui/async-await/async-closures/def-path.rs
new file mode 100644
index 00000000000..2883a1715b0
--- /dev/null
+++ b/tests/ui/async-await/async-closures/def-path.rs
@@ -0,0 +1,14 @@
+// compile-flags: -Zverbose-internals
+// edition:2021
+
+#![feature(async_closure)]
+
+fn main() {
+    let x = async || {};
+    //~^ NOTE the expected `async` closure body
+    let () = x();
+    //~^ ERROR mismatched types
+    //~| NOTE this expression has type `{static main::{closure#0}::{closure#0} upvar_tys=
+    //~| NOTE expected `async` closure body, found `()`
+    //~| NOTE expected `async` closure body `{static main::{closure#0}::{closure#0}
+}
diff --git a/tests/ui/async-await/async-closures/def-path.stderr b/tests/ui/async-await/async-closures/def-path.stderr
new file mode 100644
index 00000000000..4b37e50aac4
--- /dev/null
+++ b/tests/ui/async-await/async-closures/def-path.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+  --> $DIR/def-path.rs:9:9
+   |
+LL |     let x = async || {};
+   |                      -- the expected `async` closure body
+LL |
+LL |     let () = x();
+   |         ^^   --- this expression has type `{static main::{closure#0}::{closure#0} upvar_tys=?7t witness=?8t}`
+   |         |
+   |         expected `async` closure body, found `()`
+   |
+   = note: expected `async` closure body `{static main::{closure#0}::{closure#0} upvar_tys=?7t witness=?8t}`
+                         found unit type `()`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.