about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/hir/lowering/expr.rs22
-rw-r--r--src/librustc/hir/lowering/item.rs6
-rw-r--r--src/librustc/hir/mod.rs35
-rw-r--r--src/librustc_typeck/check/generator_interior.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs2
5 files changed, 52 insertions, 15 deletions
diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index 9dcecedd97c..7630ec8c24f 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -89,9 +89,14 @@ impl LoweringContext<'_> {
                 hir::MatchSource::Normal,
             ),
             ExprKind::Async(capture_clause, closure_node_id, ref block) => {
-                self.make_async_expr(capture_clause, closure_node_id, None, block.span, |this| {
-                    this.with_new_scopes(|this| this.lower_block_expr(block))
-                })
+                self.make_async_expr(
+                    capture_clause,
+                    closure_node_id,
+                    None,
+                    block.span,
+                    hir::AsyncGeneratorKind::Block,
+                    |this| this.with_new_scopes(|this| this.lower_block_expr(block)),
+                )
             }
             ExprKind::Await(ref expr) => self.lower_expr_await(e.span, expr),
             ExprKind::Closure(
@@ -440,6 +445,7 @@ impl LoweringContext<'_> {
         closure_node_id: NodeId,
         ret_ty: Option<AstP<Ty>>,
         span: Span,
+        async_gen_kind: hir::AsyncGeneratorKind,
         body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr,
     ) -> hir::ExprKind {
         let capture_clause = self.lower_capture_clause(capture_clause);
@@ -453,7 +459,7 @@ impl LoweringContext<'_> {
         };
         let decl = self.lower_fn_decl(&ast_decl, None, /* impl trait allowed */ false, None);
         let body_id = self.lower_fn_body(&ast_decl, |this| {
-            this.generator_kind = Some(hir::GeneratorKind::Async);
+            this.generator_kind = Some(hir::GeneratorKind::Async(async_gen_kind));
             body(this)
         });
 
@@ -505,7 +511,7 @@ impl LoweringContext<'_> {
     /// ```
     fn lower_expr_await(&mut self, await_span: Span, expr: &Expr) -> hir::ExprKind {
         match self.generator_kind {
-            Some(hir::GeneratorKind::Async) => {},
+            Some(hir::GeneratorKind::Async(_)) => {},
             Some(hir::GeneratorKind::Gen) |
             None => {
                 let mut err = struct_span_err!(
@@ -710,7 +716,7 @@ impl LoweringContext<'_> {
                     Movability::Static => hir::GeneratorMovability::Static,
                 })
             },
-            Some(hir::GeneratorKind::Async) => {
+            Some(hir::GeneratorKind::Async(_)) => {
                 bug!("non-`async` closure body turned `async` during lowering");
             },
             None => {
@@ -769,7 +775,7 @@ impl LoweringContext<'_> {
                     None
                 };
                 let async_body = this.make_async_expr(
-                    capture_clause, closure_id, async_ret_ty, body.span,
+                    capture_clause, closure_id, async_ret_ty, body.span, hir::AsyncGeneratorKind::Closure,
                     |this| {
                         this.with_new_scopes(|this| this.lower_expr(body))
                     }
@@ -988,7 +994,7 @@ impl LoweringContext<'_> {
     fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::ExprKind {
         match self.generator_kind {
             Some(hir::GeneratorKind::Gen) => {},
-            Some(hir::GeneratorKind::Async) => {
+            Some(hir::GeneratorKind::Async(_)) => {
                 span_err!(
                     self.sess,
                     span,
diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs
index 7159db736a7..548a2fedfff 100644
--- a/src/librustc/hir/lowering/item.rs
+++ b/src/librustc/hir/lowering/item.rs
@@ -1222,7 +1222,11 @@ impl LoweringContext<'_> {
             }
 
             let async_expr = this.make_async_expr(
-                CaptureBy::Value, closure_id, None, body.span,
+                CaptureBy::Value,
+                closure_id,
+                None,
+                body.span,
+                hir::AsyncGeneratorKind::Fn,
                 |this| {
                     // Create a block from the user's function body:
                     let user_body = this.lower_block_expr(body);
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 9ae661f0952..c390e4ce2a4 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -1366,17 +1366,43 @@ impl Body {
 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
          RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
 pub enum GeneratorKind {
-    /// An `async` block or function.
-    Async,
+    /// An explicit `async` block or the body of an async function.
+    Async(AsyncGeneratorKind),
+
     /// A generator literal created via a `yield` inside a closure.
     Gen,
 }
 
 impl fmt::Display for GeneratorKind {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            GeneratorKind::Async(k) => fmt::Display::fmt(k, f),
+            GeneratorKind::Gen => f.write_str("generator"),
+        }
+    }
+}
+
+/// The type of source expression that caused this generator to be created.
+// Not `IsAsync` because we want to eventually add support for `AsyncGen`
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
+         RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
+pub enum AsyncGeneratorKind {
+    /// An explicit `async` block written by the user.
+    Block,
+
+    /// An explicit `async` block written by the user.
+    Closure,
+
+    /// The `async` block generated as the body of an async function.
+    Fn,
+}
+
+impl fmt::Display for AsyncGeneratorKind {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.write_str(match self {
-            GeneratorKind::Async => "`async` object",
-            GeneratorKind::Gen => "generator",
+            AsyncGeneratorKind::Block => "`async` block",
+            AsyncGeneratorKind::Closure => "`async` closure body",
+            AsyncGeneratorKind::Fn => "`async` fn body",
         })
     }
 }
@@ -1758,6 +1784,7 @@ pub struct Destination {
 pub enum GeneratorMovability {
     /// May contain self-references, `!Unpin`.
     Static,
+
     /// Must not contain self-references, `Unpin`.
     Movable,
 }
diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs
index 4608eb51df7..c40d11503a3 100644
--- a/src/librustc_typeck/check/generator_interior.rs
+++ b/src/librustc_typeck/check/generator_interior.rs
@@ -55,7 +55,7 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
             expr_and_pat_count: 0,
             source: match self.kind { // Guess based on the kind of the current generator.
                 hir::GeneratorKind::Gen => hir::YieldSource::Yield,
-                hir::GeneratorKind::Async => hir::YieldSource::Await,
+                hir::GeneratorKind::Async(_) => hir::YieldSource::Await,
             },
         }));
 
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 720d31310a1..3ccb5f2ee5b 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4534,7 +4534,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let item_id = self.tcx().hir().get_parent_node(self.body_id);
         if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
             let body = self.tcx().hir().body(body_id);
-            if let Some(hir::GeneratorKind::Async) = body.generator_kind {
+            if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
                 let sp = expr.span;
                 // Check for `Future` implementations by constructing a predicate to
                 // prove: `<T as Future>::Output == U`