Remove identity_future
indirection
This was previously needed because the indirection used to hide some unexplained lifetime errors, which it turned out were related to the `min_choice` algorithm. Removing the indirection also solves a couple of cycle errors, large moves and makes async blocks support the `#[track_caller]` annotation.
This commit is contained in:
parent
64165aac68
commit
9f03cfc207
32 changed files with 149 additions and 361 deletions
|
@ -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.
|
||||
|
@ -63,6 +63,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
ExprKind::ForLoop(pat, head, body, opt_label) => {
|
||||
return self.lower_expr_for(e, pat, head, body, *opt_label);
|
||||
}
|
||||
// Similarly, async blocks do not use `e.id` but rather `closure_node_id`.
|
||||
ExprKind::Async(capture_clause, closure_node_id, block) => {
|
||||
let hir_id = self.lower_node_id(*closure_node_id);
|
||||
self.lower_attrs(hir_id, &e.attrs);
|
||||
return self.make_async_expr(
|
||||
*capture_clause,
|
||||
hir_id,
|
||||
*closure_node_id,
|
||||
None,
|
||||
e.span,
|
||||
hir::AsyncGeneratorKind::Block,
|
||||
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
|
||||
);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
|
@ -182,15 +196,6 @@ 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(
|
||||
*capture_clause,
|
||||
hir_id,
|
||||
*closure_node_id,
|
||||
None,
|
||||
e.span,
|
||||
hir::AsyncGeneratorKind::Block,
|
||||
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
|
||||
),
|
||||
ExprKind::Await(expr) => {
|
||||
let dot_await_span = if expr.span.hi() < e.span.hi() {
|
||||
let span_with_whitespace = self
|
||||
|
@ -324,7 +329,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(..) | ExprKind::Async(..) => {
|
||||
unreachable!("already handled")
|
||||
}
|
||||
|
||||
ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span),
|
||||
};
|
||||
|
@ -586,9 +593,9 @@ 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,
|
||||
|
@ -599,7 +606,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
span: Span,
|
||||
async_gen_kind: hir::AsyncGeneratorKind,
|
||||
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
|
||||
) -> hir::ExprKind<'hir> {
|
||||
) -> hir::Expr<'hir> {
|
||||
let output = ret_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span)));
|
||||
|
||||
// Resume argument type: `ResumeTy`
|
||||
|
@ -664,13 +671,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
};
|
||||
|
||||
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());
|
||||
|
||||
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,
|
||||
&[Attribute {
|
||||
|
@ -689,22 +695,7 @@ 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])
|
||||
hir::Expr { hir_id, kind: generator_kind, span: self.lower_span(span) }
|
||||
}
|
||||
|
||||
/// Desugar `<expr>.await` into:
|
||||
|
@ -1010,7 +1001,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);
|
||||
|
@ -1019,7 +1010,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
None
|
||||
};
|
||||
|
||||
let async_body = this.make_async_expr(
|
||||
this.make_async_expr(
|
||||
capture_clause,
|
||||
closure_hir_id,
|
||||
inner_closure_id,
|
||||
|
@ -1027,8 +1018,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
body.span,
|
||||
hir::AsyncGeneratorKind::Closure,
|
||||
|this| this.with_new_scopes(|this| this.lower_expr_mut(body)),
|
||||
);
|
||||
this.expr(fn_decl_span, async_body)
|
||||
)
|
||||
});
|
||||
body_id
|
||||
});
|
||||
|
|
|
@ -1180,7 +1180,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
},
|
||||
);
|
||||
|
||||
(this.arena.alloc_from_iter(parameters), this.expr(body.span, async_expr))
|
||||
(this.arena.alloc_from_iter(parameters), async_expr)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue