diff options
| -rw-r--r-- | src/librustc/hir/lowering/expr.rs | 22 | ||||
| -rw-r--r-- | src/librustc/hir/lowering/item.rs | 6 | ||||
| -rw-r--r-- | src/librustc/hir/mod.rs | 35 | ||||
| -rw-r--r-- | src/librustc_typeck/check/generator_interior.rs | 2 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 2 |
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` |
