about summary refs log tree commit diff
path: root/compiler/rustc_ast_lowering/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_ast_lowering/src')
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs71
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs89
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs57
3 files changed, 93 insertions, 124 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index eb1a1d15027..5846f17c539 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -195,39 +195,37 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     binder,
                     capture_clause,
                     constness,
-                    asyncness,
+                    coro_kind,
                     movability,
                     fn_decl,
                     body,
                     fn_decl_span,
                     fn_arg_span,
-                }) => {
-                    if let Async::Yes { closure_id, .. } = asyncness {
-                        self.lower_expr_async_closure(
-                            binder,
-                            *capture_clause,
-                            e.id,
-                            hir_id,
-                            *closure_id,
-                            fn_decl,
-                            body,
-                            *fn_decl_span,
-                            *fn_arg_span,
-                        )
-                    } else {
-                        self.lower_expr_closure(
-                            binder,
-                            *capture_clause,
-                            e.id,
-                            *constness,
-                            *movability,
-                            fn_decl,
-                            body,
-                            *fn_decl_span,
-                            *fn_arg_span,
-                        )
-                    }
-                }
+                }) => match coro_kind {
+                    CoroutineKind::Async { closure_id, .. }
+                    | CoroutineKind::Gen { closure_id, .. } => self.lower_expr_async_closure(
+                        binder,
+                        *capture_clause,
+                        e.id,
+                        hir_id,
+                        *closure_id,
+                        fn_decl,
+                        body,
+                        *fn_decl_span,
+                        *fn_arg_span,
+                    ),
+                    CoroutineKind::None => self.lower_expr_closure(
+                        binder,
+                        *capture_clause,
+                        e.id,
+                        *constness,
+                        *movability,
+                        fn_decl,
+                        body,
+                        *fn_decl_span,
+                        *fn_arg_span,
+                    ),
+                },
                 ExprKind::Block(blk, opt_label) => {
                     let opt_label = self.lower_label(*opt_label);
                     hir::ExprKind::Block(self.lower_block(blk, opt_label.is_some()), opt_label)
@@ -935,7 +933,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
         let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
         // Lower outside new scope to preserve `is_in_loop_condition`.
-        let fn_decl = self.lower_fn_decl(decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);
+        let fn_decl = self.lower_fn_decl(
+            decl,
+            closure_id,
+            fn_decl_span,
+            FnDeclKind::Closure,
+            CoroutineKind::None,
+        );
 
         let c = self.arena.alloc(hir::Closure {
             def_id: self.local_def_id(closure_id),
@@ -1050,8 +1054,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
         // We need to lower the declaration outside the new scope, because we
         // have to conserve the state of being inside a loop condition for the
         // closure argument types.
-        let fn_decl =
-            self.lower_fn_decl(&outer_decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);
+        let fn_decl = self.lower_fn_decl(
+            &outer_decl,
+            closure_id,
+            fn_decl_span,
+            FnDeclKind::Closure,
+            CoroutineKind::None,
+        );
 
         let c = self.arena.alloc(hir::Closure {
             def_id: self.local_def_id(closure_id),
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 852555048fe..5d32e1a78f1 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1,5 +1,3 @@
-use crate::FnReturnTransformation;
-
 use super::errors::{InvalidAbi, InvalidAbiReason, InvalidAbiSuggestion, MisplacedRelaxTraitBound};
 use super::ResolverAstLoweringExt;
 use super::{AstOwner, ImplTraitContext, ImplTraitPosition};
@@ -208,35 +206,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     // `impl Future<Output = T>` here because lower_body
                     // only cares about the input argument patterns in the function
                     // declaration (decl), not the return types.
-                    let asyncness = header.asyncness;
-                    let genness = header.genness;
+                    let coro_kind = header.coro_kind;
                     let body_id = this.lower_maybe_coroutine_body(
                         span,
                         hir_id,
                         decl,
-                        asyncness,
-                        genness,
+                        coro_kind,
                         body.as_deref(),
                     );
 
                     let itctx = ImplTraitContext::Universal;
                     let (generics, decl) =
                         this.lower_generics(generics, header.constness, id, &itctx, |this| {
-                            let ret_id = asyncness
-                                .opt_return_id()
-                                .map(|(node_id, span)| {
-                                    crate::FnReturnTransformation::Async(node_id, span)
-                                })
-                                .or_else(|| match genness {
-                                    Gen::Yes { span, closure_id: _, return_impl_trait_id } => {
-                                        Some(crate::FnReturnTransformation::Iterator(
-                                            return_impl_trait_id,
-                                            span,
-                                        ))
-                                    }
-                                    _ => None,
-                                });
-                            this.lower_fn_decl(decl, id, *fn_sig_span, FnDeclKind::Fn, ret_id)
+                            this.lower_fn_decl(decl, id, *fn_sig_span, FnDeclKind::Fn, coro_kind)
                         });
                     let sig = hir::FnSig {
                         decl,
@@ -620,7 +602,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                                     i.id,
                                     sig.span,
                                     FnDeclKind::ExternFn,
-                                    None,
+                                    CoroutineKind::None,
                                 ),
                                 this.lower_fn_params_to_names(fdec),
                             )
@@ -747,28 +729,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 (generics, kind, expr.is_some())
             }
             AssocItemKind::Fn(box Fn { sig, generics, body: None, .. }) => {
-                let asyncness = sig.header.asyncness;
                 let names = self.lower_fn_params_to_names(&sig.decl);
                 let (generics, sig) = self.lower_method_sig(
                     generics,
                     sig,
                     i.id,
                     FnDeclKind::Trait,
-                    asyncness
-                        .opt_return_id()
-                        .map(|(node_id, span)| crate::FnReturnTransformation::Async(node_id, span)),
+                    sig.header.coro_kind,
                 );
                 (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
             }
             AssocItemKind::Fn(box Fn { sig, generics, body: Some(body), .. }) => {
-                let asyncness = sig.header.asyncness;
-                let genness = sig.header.genness;
                 let body_id = self.lower_maybe_coroutine_body(
                     i.span,
                     hir_id,
                     &sig.decl,
-                    asyncness,
-                    genness,
+                    sig.header.coro_kind,
                     Some(body),
                 );
                 let (generics, sig) = self.lower_method_sig(
@@ -776,9 +752,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     sig,
                     i.id,
                     FnDeclKind::Trait,
-                    asyncness
-                        .opt_return_id()
-                        .map(|(node_id, span)| crate::FnReturnTransformation::Async(node_id, span)),
+                    sig.header.coro_kind,
                 );
                 (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true)
             }
@@ -867,14 +841,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 },
             ),
             AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => {
-                let asyncness = sig.header.asyncness;
-                let genness = sig.header.genness;
+                self.current_item = Some(i.span);
                 let body_id = self.lower_maybe_coroutine_body(
                     i.span,
                     hir_id,
                     &sig.decl,
-                    asyncness,
-                    genness,
+                    sig.header.coro_kind,
                     body.as_deref(),
                 );
                 let (generics, sig) = self.lower_method_sig(
@@ -882,9 +854,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     sig,
                     i.id,
                     if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
-                    asyncness
-                        .opt_return_id()
-                        .map(|(node_id, span)| crate::FnReturnTransformation::Async(node_id, span)),
+                    sig.header.coro_kind,
                 );
 
                 (generics, hir::ImplItemKind::Fn(sig, body_id))
@@ -1055,15 +1025,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
         span: Span,
         fn_id: hir::HirId,
         decl: &FnDecl,
-        asyncness: Async,
-        genness: Gen,
+        coro_kind: CoroutineKind,
         body: Option<&Block>,
     ) -> hir::BodyId {
-        let (closure_id, body) = match (asyncness, genness, body) {
-            // FIXME(eholk): do something reasonable for `async gen fn`. Probably that's an error
-            // for now since it's not supported.
-            (Async::Yes { closure_id, .. }, _, Some(body))
-            | (_, Gen::Yes { closure_id, .. }, Some(body)) => (closure_id, body),
+        let (closure_id, body) = match (coro_kind, body) {
+            (
+                CoroutineKind::Async { closure_id, .. } | CoroutineKind::Gen { closure_id, .. },
+                Some(body),
+            ) => (closure_id, body),
             _ => return self.lower_fn_body_block(span, decl, body),
         };
 
@@ -1232,8 +1201,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
                 this.expr_block(body)
             };
-            let coroutine_expr = match (asyncness, genness) {
-                (Async::Yes { .. }, _) => this.make_async_expr(
+            let coroutine_expr = match coro_kind {
+                CoroutineKind::Async { .. } => this.make_async_expr(
                     CaptureBy::Value { move_kw: rustc_span::DUMMY_SP },
                     closure_id,
                     None,
@@ -1241,7 +1210,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     hir::CoroutineSource::Fn,
                     mkbody,
                 ),
-                (_, Gen::Yes { .. }) => this.make_gen_expr(
+                CoroutineKind::Gen { .. } => this.make_gen_expr(
                     CaptureBy::Value { move_kw: rustc_span::DUMMY_SP },
                     closure_id,
                     None,
@@ -1249,7 +1218,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     hir::CoroutineSource::Fn,
                     mkbody,
                 ),
-                _ => unreachable!("we must have either an async fn or a gen fn"),
+                CoroutineKind::None => unreachable!("we must have either an async fn or a gen fn"),
             };
 
             let hir_id = this.lower_node_id(closure_id);
@@ -1266,21 +1235,26 @@ impl<'hir> LoweringContext<'_, 'hir> {
         sig: &FnSig,
         id: NodeId,
         kind: FnDeclKind,
-        transform_return_type: Option<FnReturnTransformation>,
+        coro_kind: CoroutineKind,
     ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
         let header = self.lower_fn_header(sig.header);
         let itctx = ImplTraitContext::Universal;
         let (generics, decl) =
             self.lower_generics(generics, sig.header.constness, id, &itctx, |this| {
-                this.lower_fn_decl(&sig.decl, id, sig.span, kind, transform_return_type)
+                this.lower_fn_decl(&sig.decl, id, sig.span, kind, coro_kind)
             });
         (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
     }
 
     fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
+        let asyncness = if let CoroutineKind::Async { span, .. } = h.coro_kind {
+            hir::IsAsync::Async(span)
+        } else {
+            hir::IsAsync::NotAsync
+        };
         hir::FnHeader {
             unsafety: self.lower_unsafety(h.unsafety),
-            asyncness: self.lower_asyncness(h.asyncness),
+            asyncness: asyncness,
             constness: self.lower_constness(h.constness),
             abi: self.lower_extern(h.ext),
         }
@@ -1322,13 +1296,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
         });
     }
 
-    fn lower_asyncness(&mut self, a: Async) -> hir::IsAsync {
-        match a {
-            Async::Yes { span, .. } => hir::IsAsync::Async(span),
-            Async::No => hir::IsAsync::NotAsync,
-        }
-    }
-
     pub(super) fn lower_constness(&mut self, c: Const) -> hir::Constness {
         match c {
             Const::Yes(_) => hir::Constness::Const,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 96a413e9f73..92650f0c47e 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -493,21 +493,6 @@ enum ParenthesizedGenericArgs {
     Err,
 }
 
-/// Describes a return type transformation that can be performed by `LoweringContext::lower_fn_decl`
-#[derive(Debug)]
-enum FnReturnTransformation {
-    /// Replaces a return type `T` with `impl Future<Output = T>`.
-    ///
-    /// The `NodeId` is the ID of the return type `impl Trait` item, and the `Span` points to the
-    /// `async` keyword.
-    Async(NodeId, Span),
-    /// Replaces a return type `T` with `impl Iterator<Item = T>`.
-    ///
-    /// The `NodeId` is the ID of the return type `impl Trait` item, and the `Span` points to the
-    /// `gen` keyword.
-    Iterator(NodeId, Span),
-}
-
 impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn create_def(
         &mut self,
@@ -1374,7 +1359,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     generic_params,
                     unsafety: self.lower_unsafety(f.unsafety),
                     abi: self.lower_extern(f.ext),
-                    decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
+                    decl: self.lower_fn_decl(
+                        &f.decl,
+                        t.id,
+                        t.span,
+                        FnDeclKind::Pointer,
+                        CoroutineKind::None,
+                    ),
                     param_names: self.lower_fn_params_to_names(&f.decl),
                 }))
             }
@@ -1809,7 +1800,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         fn_node_id: NodeId,
         fn_span: Span,
         kind: FnDeclKind,
-        transform_return_type: Option<FnReturnTransformation>,
+        coro: CoroutineKind,
     ) -> &'hir hir::FnDecl<'hir> {
         let c_variadic = decl.c_variadic();
 
@@ -1838,12 +1829,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             self.lower_ty_direct(&param.ty, &itctx)
         }));
 
-        let output = match transform_return_type {
-            Some(transform) => {
+        let output = match coro {
+            CoroutineKind::Async { .. } | CoroutineKind::Gen { .. } => {
                 let fn_def_id = self.local_def_id(fn_node_id);
-                self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, transform, kind, fn_span)
+                self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind, fn_span)
             }
-            None => match &decl.output {
+            CoroutineKind::None => match &decl.output {
                 FnRetTy::Ty(ty) => {
                     let context = if kind.return_impl_trait_allowed() {
                         let fn_def_id = self.local_def_id(fn_node_id);
@@ -1910,16 +1901,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         &mut self,
         output: &FnRetTy,
         fn_def_id: LocalDefId,
-        transform: FnReturnTransformation,
+        coro: CoroutineKind,
         fn_kind: FnDeclKind,
         fn_span: Span,
     ) -> hir::FnRetTy<'hir> {
         let span = self.lower_span(fn_span);
         let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
 
-        let opaque_ty_node_id = match transform {
-            FnReturnTransformation::Async(opaque_ty_node_id, _)
-            | FnReturnTransformation::Iterator(opaque_ty_node_id, _) => opaque_ty_node_id,
+        let opaque_ty_node_id = match coro {
+            CoroutineKind::Async { return_impl_trait_id, .. }
+            | CoroutineKind::Gen { return_impl_trait_id, .. } => return_impl_trait_id,
+            CoroutineKind::None => {
+                unreachable!("lower_coroutine_fn_ret_ty must be called with either Async or Gen")
+            }
         };
 
         let captured_lifetimes: Vec<_> = self
@@ -1939,7 +1933,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             |this| {
                 let future_bound = this.lower_coroutine_fn_output_type_to_future_bound(
                     output,
-                    transform,
+                    coro,
                     span,
                     ImplTraitContext::ReturnPositionOpaqueTy {
                         origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
@@ -1958,7 +1952,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_coroutine_fn_output_type_to_future_bound(
         &mut self,
         output: &FnRetTy,
-        transform: FnReturnTransformation,
+        coro: CoroutineKind,
         span: Span,
         nested_impl_trait_context: ImplTraitContext,
     ) -> hir::GenericBound<'hir> {
@@ -1974,11 +1968,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         };
 
         // "<Output|Item = T>"
-        let (symbol, lang_item) = match transform {
-            FnReturnTransformation::Async(..) => (hir::FN_OUTPUT_NAME, hir::LangItem::Future),
-            FnReturnTransformation::Iterator(..) => {
-                (hir::ITERATOR_ITEM_NAME, hir::LangItem::Iterator)
-            }
+        let (symbol, lang_item) = match coro {
+            CoroutineKind::Async { .. } => (hir::FN_OUTPUT_NAME, hir::LangItem::Future),
+            CoroutineKind::Gen { .. } => (hir::ITERATOR_ITEM_NAME, hir::LangItem::Iterator),
+            CoroutineKind::None => panic!("attemping to lower output type of non-coroutine fn"),
         };
 
         let future_args = self.arena.alloc(hir::GenericArgs {