diff options
Diffstat (limited to 'compiler/rustc_ast_lowering/src/expr.rs')
-rw-r--r-- | compiler/rustc_ast_lowering/src/expr.rs | 92 |
1 files changed, 39 insertions, 53 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index ffb30b1b3..1b1c4765b 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1,6 +1,6 @@ use super::errors::{ AsyncGeneratorsNotSupported, AsyncNonMoveClosureNotSupported, AwaitOnlyInAsyncFnAndBlocks, - BaseExpressionDoubleDot, ClosureCannotBeStatic, FunctionalRecordUpdateDestructuringAssignemnt, + BaseExpressionDoubleDot, ClosureCannotBeStatic, FunctionalRecordUpdateDestructuringAssignment, GeneratorTooManyParameters, InclusiveRangeWithNoEnd, NotSupportedForLifetimeBinderAsyncClosure, UnderscoreExprLhsAssign, }; @@ -32,7 +32,7 @@ impl<'hir> LoweringContext<'_, 'hir> { pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> { ensure_sufficient_stack(|| { match &e.kind { - // Paranthesis expression does not have a HirId and is handled specially. + // Parenthesis expression does not have a HirId and is handled specially. ExprKind::Paren(ex) => { let mut ex = self.lower_expr_mut(ex); // Include parens in span, but only if it is a super-span. @@ -70,7 +70,6 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_attrs(hir_id, &e.attrs); let kind = match &e.kind { - ExprKind::Box(inner) => hir::ExprKind::Box(self.lower_expr(inner)), ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)), ExprKind::ConstBlock(anon_const) => { let anon_const = self.lower_anon_const(anon_const); @@ -174,10 +173,9 @@ impl<'hir> LoweringContext<'_, 'hir> { self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))), hir::MatchSource::Normal, ), - ExprKind::Async(capture_clause, closure_node_id, block) => self.make_async_expr( + ExprKind::Async(capture_clause, block) => self.make_async_expr( *capture_clause, - hir_id, - *closure_node_id, + e.id, None, e.span, hir::AsyncGeneratorKind::Block, @@ -316,7 +314,9 @@ impl<'hir> LoweringContext<'_, 'hir> { ), ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr), - ExprKind::Paren(_) | ExprKind::ForLoop(..) => unreachable!("already handled"), + ExprKind::Paren(_) | ExprKind::ForLoop(..) => { + unreachable!("already handled") + } ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span), }; @@ -434,7 +434,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // `if let pat = val` or `if foo && let pat = val`, as we _do_ want `val` to live beyond the // condition in this case. // - // In order to mantain the drop behavior for the non `let` parts of the condition, + // In order to maintain the drop behavior for the non `let` parts of the condition, // we still wrap them in terminating scopes, e.g. `if foo && let pat = val` essentially // gets transformed into `if { let _t = foo; _t } && let pat = val` match &cond.kind { @@ -578,14 +578,13 @@ impl<'hir> LoweringContext<'_, 'hir> { /// This results in: /// /// ```text - /// std::future::identity_future(static move? |_task_context| -> <ret_ty> { + /// static move? |_task_context| -> <ret_ty> { /// <body> - /// }) + /// } /// ``` pub(super) fn make_async_expr( &mut self, capture_clause: CaptureBy, - outer_hir_id: hir::HirId, closure_node_id: NodeId, ret_ty: Option<hir::FnRetTy<'hir>>, span: Span, @@ -638,33 +637,36 @@ impl<'hir> LoweringContext<'_, 'hir> { }); // `static |_task_context| -> <ret_ty> { body }`: - let generator_kind = { - let c = self.arena.alloc(hir::Closure { - def_id: self.local_def_id(closure_node_id), - binder: hir::ClosureBinder::Default, - capture_clause, - bound_generic_params: &[], - fn_decl, - body, - fn_decl_span: self.lower_span(span), - fn_arg_span: None, - movability: Some(hir::Movability::Static), - constness: hir::Constness::NotConst, - }); - - hir::ExprKind::Closure(c) - }; - - let hir_id = self.lower_node_id(closure_node_id); - let unstable_span = - self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone()); + hir::ExprKind::Closure(self.arena.alloc(hir::Closure { + def_id: self.local_def_id(closure_node_id), + binder: hir::ClosureBinder::Default, + capture_clause, + bound_generic_params: &[], + fn_decl, + body, + fn_decl_span: self.lower_span(span), + fn_arg_span: None, + movability: Some(hir::Movability::Static), + constness: hir::Constness::NotConst, + })) + } + /// Forwards a possible `#[track_caller]` annotation from `outer_hir_id` to + /// `inner_hir_id` in case the `closure_track_caller` feature is enabled. + pub(super) fn maybe_forward_track_caller( + &mut self, + span: Span, + outer_hir_id: hir::HirId, + inner_hir_id: hir::HirId, + ) { if self.tcx.features().closure_track_caller && let Some(attrs) = self.attrs.get(&outer_hir_id.local_id) && attrs.into_iter().any(|attr| attr.has_name(sym::track_caller)) { + let unstable_span = + self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone()); self.lower_attrs( - hir_id, + inner_hir_id, &[Attribute { kind: AttrKind::Normal(ptr::P(NormalAttr { item: AttrItem { @@ -680,23 +682,6 @@ impl<'hir> LoweringContext<'_, 'hir> { }], ); } - - let generator = hir::Expr { hir_id, kind: generator_kind, span: self.lower_span(span) }; - - // FIXME(swatinem): - // For some reason, the async block needs to flow through *any* - // call (like the identity function), as otherwise type and lifetime - // inference have a hard time figuring things out. - // Without this, we would get: - // E0720 in tests/ui/impl-trait/in-trait/default-body-with-rpit.rs - // E0700 in tests/ui/self/self_lifetime-async.rs - - // `future::identity_future`: - let identity_future = - self.expr_lang_item_path(unstable_span, hir::LangItem::IdentityFuture, None); - - // `future::identity_future(generator)`: - hir::ExprKind::Call(self.arena.alloc(identity_future), arena_vec![self; generator]) } /// Desugar `<expr>.await` into: @@ -1002,7 +987,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } // Transform `async |x: u8| -> X { ... }` into - // `|x: u8| identity_future(|| -> X { ... })`. + // `|x: u8| || -> X { ... }`. let body_id = this.lower_fn_body(&outer_decl, |this| { let async_ret_ty = if let FnRetTy::Ty(ty) = &decl.output { let itctx = ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock); @@ -1013,14 +998,15 @@ impl<'hir> LoweringContext<'_, 'hir> { let async_body = this.make_async_expr( capture_clause, - closure_hir_id, inner_closure_id, async_ret_ty, body.span, hir::AsyncGeneratorKind::Closure, |this| this.with_new_scopes(|this| this.lower_expr_mut(body)), ); - this.expr(fn_decl_span, async_body) + let hir_id = this.lower_node_id(inner_closure_id); + this.maybe_forward_track_caller(body.span, closure_hir_id, hir_id); + hir::Expr { hir_id, kind: async_body, span: this.lower_span(body.span) } }); body_id }); @@ -1246,7 +1232,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); let fields_omitted = match &se.rest { StructRest::Base(e) => { - self.tcx.sess.emit_err(FunctionalRecordUpdateDestructuringAssignemnt { + self.tcx.sess.emit_err(FunctionalRecordUpdateDestructuringAssignment { span: e.span, }); true |