about summary refs log tree commit diff
path: root/src/librustc/hir/map
diff options
context:
space:
mode:
authorTaylor Cramer <cramertj@google.com>2018-06-06 15:50:59 -0700
committerTaylor Cramer <cramertj@google.com>2018-06-21 22:36:36 -0700
commitcf844b547dbec1f23982fca8e07ec65800ed5d6d (patch)
treea5420599dea5829f105d2a12bb14a3102141a749 /src/librustc/hir/map
parent589446e19cbf7a2c7eddf80b490992d31134015c (diff)
downloadrust-cf844b547dbec1f23982fca8e07ec65800ed5d6d.tar.gz
rust-cf844b547dbec1f23982fca8e07ec65800ed5d6d.zip
async await desugaring and tests
Diffstat (limited to 'src/librustc/hir/map')
-rw-r--r--src/librustc/hir/map/def_collector.rs40
1 files changed, 36 insertions, 4 deletions
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index 8aa5dd4ad80..335e38bbe7e 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -99,6 +99,21 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
             ItemKind::Mod(..) if i.ident == keywords::Invalid.ident() => {
                 return visit::walk_item(self, i);
             }
+            ItemKind::Fn(_, FnHeader { asyncness: IsAsync::Async(async_node_id), .. }, ..) => {
+                // For async functions, we need to create their inner defs inside of a
+                // closure to match their desugared representation.
+                let fn_def_data = DefPathData::ValueNs(i.ident.name.as_interned_str());
+                let fn_def = self.create_def(i.id, fn_def_data, ITEM_LIKE_SPACE, i.span);
+                return self.with_parent(fn_def, |this| {
+                    let closure_def = this.create_def(async_node_id,
+                                          DefPathData::ClosureExpr,
+                                          REGULAR_SPACE,
+                                          i.span);
+                    this.with_parent(closure_def, |this| {
+                        visit::walk_item(this, i);
+                    })
+                });
+            }
             ItemKind::Mod(..) => DefPathData::Module(i.ident.name.as_interned_str()),
             ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
                 DefPathData::ValueNs(i.ident.name.as_interned_str()),
@@ -227,15 +242,32 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
 
         match expr.node {
             ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id),
-            ExprKind::Closure(..) => {
-                let def = self.create_def(expr.id,
+            ExprKind::Closure(_, asyncness, ..) => {
+                let closure_def = self.create_def(expr.id,
                                           DefPathData::ClosureExpr,
                                           REGULAR_SPACE,
                                           expr.span);
-                self.parent_def = Some(def);
+                self.parent_def = Some(closure_def);
+
+                // Async closures desugar to closures inside of closures, so
+                // we must create two defs.
+                if let IsAsync::Async(async_id) = asyncness {
+                    let async_def = self.create_def(async_id,
+                                                    DefPathData::ClosureExpr,
+                                                    REGULAR_SPACE,
+                                                    expr.span);
+                    self.parent_def = Some(async_def);
+                }
+            }
+            ExprKind::Async(_, async_id, _) => {
+                let async_def = self.create_def(async_id,
+                                                DefPathData::ClosureExpr,
+                                                REGULAR_SPACE,
+                                                expr.span);
+                self.parent_def = Some(async_def);
             }
             _ => {}
-        }
+        };
 
         visit::walk_expr(self, expr);
         self.parent_def = parent_def;