diff options
Diffstat (limited to 'compiler/rustc_ast_lowering/src')
| -rw-r--r-- | compiler/rustc_ast_lowering/src/expr.rs | 71 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/item.rs | 89 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/lib.rs | 57 |
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(¶m.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 { |
