Skip to content

Commit 78274bc

Browse files
Don't create AST fragments when lowering to HIR
1 parent e419168 commit 78274bc

File tree

2 files changed

+34
-30
lines changed

2 files changed

+34
-30
lines changed

src/librustc_ast_lowering/expr.rs

+33-29
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use rustc_hir as hir;
1010
use rustc_hir::def::Res;
1111
use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
1212
use rustc_span::symbol::{sym, Symbol};
13-
use rustc_span::DUMMY_SP;
1413

1514
impl<'hir> LoweringContext<'_, 'hir> {
1615
fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'hir>] {
@@ -471,6 +470,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
471470
}
472471
}
473472

473+
/// Lower an `async` construct to a generator that is then wrapped so it implements `Future`.
474+
///
475+
/// This results in:
476+
///
477+
/// ```text
478+
/// std::future::from_generator(static move? |_task_context| -> <ret_ty> {
479+
/// <body>
480+
/// })
481+
/// ```
474482
pub(super) fn make_async_expr(
475483
&mut self,
476484
capture_clause: CaptureBy,
@@ -481,46 +489,42 @@ impl<'hir> LoweringContext<'_, 'hir> {
481489
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
482490
) -> hir::ExprKind<'hir> {
483491
let output = match ret_ty {
484-
Some(ty) => FnRetTy::Ty(ty),
485-
None => FnRetTy::Default(span),
492+
Some(ty) => hir::FnRetTy::Return(self.lower_ty(&ty, ImplTraitContext::disallowed())),
493+
None => hir::FnRetTy::DefaultReturn(span),
486494
};
487495

488-
let task_context_id = self.resolver.next_node_id();
489-
let task_context_hid = self.lower_node_id(task_context_id);
496+
// Resume argument type. We let the compiler infer this to simplify the lowering. It is
497+
// fully constrained by `future::from_generator`.
498+
let input_ty = hir::Ty { hir_id: self.next_id(), kind: hir::TyKind::Infer, span };
490499

491-
let arg_ty = Ty { id: self.resolver.next_node_id(), kind: TyKind::Infer, span: DUMMY_SP };
492-
let arg_pat = Pat {
493-
id: task_context_id,
494-
kind: PatKind::Ident(
495-
BindingMode::ByValue(Mutability::Mut),
496-
Ident::with_dummy_span(sym::_task_context),
497-
None,
498-
),
499-
span: DUMMY_SP,
500-
};
501-
let ast_decl = FnDecl {
502-
inputs: vec![Param {
503-
attrs: AttrVec::new(),
504-
ty: AstP(arg_ty),
505-
pat: AstP(arg_pat),
506-
id: self.resolver.next_node_id(),
507-
span: DUMMY_SP,
508-
is_placeholder: false,
509-
}],
500+
// The closure/generator `FnDecl` takes a single (resume) argument of type `input_ty`.
501+
let decl = self.arena.alloc(hir::FnDecl {
502+
inputs: arena_vec![self; input_ty],
510503
output,
511-
};
512-
let decl = self.lower_fn_decl(&ast_decl, None, /* impl trait allowed */ false, None);
513-
let body_id = self.lower_fn_body(&ast_decl, |this| {
504+
c_variadic: false,
505+
implicit_self: hir::ImplicitSelfKind::None,
506+
});
507+
508+
// Lower the argument pattern/ident. The ident is used again in the `.await` lowering.
509+
let (pat, task_context_hid) = self.pat_ident_binding_mode(
510+
span,
511+
Ident::with_dummy_span(sym::_task_context),
512+
hir::BindingAnnotation::Mutable,
513+
);
514+
let param = hir::Param { attrs: &[], hir_id: self.next_id(), pat, span };
515+
let params = arena_vec![self; param];
516+
517+
let body_id = self.lower_body(move |this| {
514518
this.generator_kind = Some(hir::GeneratorKind::Async(async_gen_kind));
515519

516520
let old_ctx = this.task_context;
517521
this.task_context = Some(task_context_hid);
518522
let res = body(this);
519523
this.task_context = old_ctx;
520-
res
524+
(params, res)
521525
});
522526

523-
// `static |task_context| -> <ret_ty> { body }`:
527+
// `static |_task_context| -> <ret_ty> { body }`:
524528
let generator_kind = hir::ExprKind::Closure(
525529
capture_clause,
526530
decl,

src/librustc_ast_lowering/item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
955955
id
956956
}
957957

958-
fn lower_body(
958+
pub(super) fn lower_body(
959959
&mut self,
960960
f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),
961961
) -> hir::BodyId {

0 commit comments

Comments
 (0)