Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 44 additions & 18 deletions compiler/rustc_ast_lowering/src/delegation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use rustc_hir::{self as hir, FnDeclFlags, QPath};
use rustc_middle::ty::Asyncness;
use rustc_span::def_id::DefId;
use rustc_span::symbol::kw;
use rustc_span::{Ident, Span, Symbol, sym};
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, sym};

use crate::delegation::generics::{GenericsGenerationResults, GenericsPosition};
use crate::delegation::resolution::resolver::DelegationResolver;
Expand Down Expand Up @@ -82,10 +82,11 @@ impl<'hir> LoweringContext<'_, 'hir> {

self.add_attrs_if_needed(&res);

let (body_id, call_expr_id, unused_target_expr) =
let (body_id, params, call_expr_id, unused_target_expr) =
self.lower_delegation_body(delegation, &res, &mut generics);

let decl = self.lower_delegation_decl(&res, &generics, call_expr_id, unused_target_expr);
let decl =
self.lower_delegation_decl(&res, params, &generics, call_expr_id, unused_target_expr);

let sig = self.lower_delegation_sig(res.sig_id, decl, span);

Expand All @@ -105,6 +106,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_delegation_decl(
&mut self,
res: &DelegationResolution,
params: &'hir [hir::Param<'hir>],
generics: &GenericsGenerationResults<'hir>,
call_expr_id: HirId,
unused_target_expr: bool,
Expand All @@ -115,14 +117,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
// The last parameter in C variadic functions is skipped in the signature,
// like during regular lowering.
let decl_param_count = param_count - c_variadic as usize;
let inputs = self.arena.alloc_from_iter((0..decl_param_count).map(|arg| hir::Ty {
hir_id: self.next_id(),
kind: hir::TyKind::InferDelegation(hir::InferDelegation::Sig(
sig_id,
hir::InferDelegationSig::Input(arg),
)),
span,
}));
let inputs =
self.arena.alloc_from_iter((0..decl_param_count).zip(params).map(|(arg, param)| {
hir::Param {
hir_id: param.hir_id,
pat: param.pat,
ty: self.arena.alloc(hir::Ty {
hir_id: self.next_id(),
kind: hir::TyKind::InferDelegation(hir::InferDelegation::Sig(
sig_id,
hir::InferDelegationSig::Input(arg),
)),
span,
}),
param_span: param.param_span,
}
}));

let output = self.arena.alloc(hir::Ty {
hir_id: self.next_id(),
Expand Down Expand Up @@ -161,7 +171,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
.set_lifetime_elision_allowed(true)
.set_c_variadic(c_variadic)
.set_splatted(splatted, inputs.len())
.unwrap(),
.unwrap()
.set_has_body(true),
})
}

Expand Down Expand Up @@ -213,7 +224,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
default_binding_modes: false,
});

(hir::Param { hir_id: self.next_id(), pat, ty_span: span, span }, pat_node_id)
let hir_id = self.next_id();
(
hir::Param {
hir_id,
pat,
param_span: span,
ty: self.arena.alloc(hir::Ty {
#[allow(deprecated)]
kind: hir::TyKind::Err(ErrorGuaranteed::unchecked_error_guaranteed()),
span: self.lower_span(span),
hir_id,
}),
},
pat_node_id,
)
}

fn generate_arg(
Expand Down Expand Up @@ -248,14 +273,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
delegation: &Delegation,
res: &DelegationResolution,
generics: &mut GenericsGenerationResults<'hir>,
) -> (hir::BodyId, HirId, bool) {
) -> (hir::BodyId, &'hir [hir::Param<'hir>], HirId, bool) {
let block = delegation.body.as_deref();
let mut call_expr_id = HirId::INVALID;
let mut unused_target_expr = false;

let block_id = self.lower_body(|this| {
let (params, block_id) = self.lower_body_with_params(|this| {
let &DelegationResolution { param_info, span, is_method, .. } = res;
let ParamInfo { param_count, .. } = param_info;
let ParamInfo { param_count, c_variadic, .. } = param_info;
let param_count = param_count - c_variadic as usize;
let arguments_to_map = &res.sig_mapping.arguments_to_map;

let mut parameters: Vec<hir::Param<'_>> = Vec::with_capacity(param_count);
Expand Down Expand Up @@ -315,7 +341,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

debug_assert_ne!(call_expr_id, HirId::INVALID);

(block_id, call_expr_id, unused_target_expr)
(block_id, params, call_expr_id, unused_target_expr)
}

fn lower_block_maybe_more_than_once(
Expand Down Expand Up @@ -600,7 +626,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
targeted_by_break: false,
});

(&[], this.mk_expr(hir::ExprKind::Block(block, None), span))
this.mk_expr(hir::ExprKind::Block(block, None), span)
});

let generics = hir::Generics::empty();
Expand Down
19 changes: 9 additions & 10 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

// The `async` desugaring takes a resume argument and maintains a `task_context`,
// whereas a generator does not.
let (inputs, params, task_context): (&[_], &[_], _) = match desugaring_kind {
let (inputs, task_context): (&[_], _) = match desugaring_kind {
hir::CoroutineDesugaring::Async | hir::CoroutineDesugaring::AsyncGen => {
// Resume argument type: `ResumeTy`
let unstable_span = self.mark_span_with_reason(
Expand All @@ -881,12 +881,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
Some(Arc::clone(self.allow_gen_future())),
);
let resume_ty = self.make_lang_item_qpath(LangItem::ResumeTy, unstable_span, None);
let input_ty = hir::Ty {
let input_ty = self.arena.alloc(hir::Ty {
hir_id: self.next_id(),
kind: hir::TyKind::Path(resume_ty),
span: unstable_span,
};
let inputs = arena_vec![self; input_ty];
});

// Lower the argument pattern/ident. The ident is used again in the `.await` lowering.
let (pat, task_context_hid) = self.pat_ident_binding_mode(
Expand All @@ -897,14 +896,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
let param = hir::Param {
hir_id: self.next_id(),
pat,
ty_span: self.lower_span(span),
span: self.lower_span(span),
ty: input_ty,
param_span: self.lower_span(span),
};
let params = arena_vec![self; param];

(inputs, params, Some(task_context_hid))
(params, Some(task_context_hid))
}
hir::CoroutineDesugaring::Gen => (&[], &[], None),
hir::CoroutineDesugaring::Gen => (&[], None),
};

let output =
Expand All @@ -913,7 +912,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let fn_decl = self.arena.alloc(hir::FnDecl {
inputs,
output,
fn_decl_kind: hir::FnDeclFlags::default(),
fn_decl_kind: hir::FnDeclFlags::default().set_has_body(true),
});

let body = self.lower_body(move |this| {
Expand All @@ -926,7 +925,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let res = body(this);
this.task_context = old_ctx;

(params, res)
res
});

let explicit_captures: &'hir [hir::ExplicitCapture] = match coroutine_source {
Expand Down
34 changes: 8 additions & 26 deletions compiler/rustc_ast_lowering/src/expr/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use rustc_hir::HirId;
use rustc_span::{Span, span_bug};

use super::{LoweringContext, MoveExprState};
use crate::FnDeclKind;
use crate::diagnostics::{ClosureCannotBeStatic, CoroutineTooManyParameters};
use crate::{DiscardParams, FnDeclKind};

impl<'hir> LoweringContext<'_, 'hir> {
// Entry point for `ExprKind::Closure`. Plain closures go through
Expand Down Expand Up @@ -133,7 +133,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
binder,
capture_clause,
closure_id,
expr_hir_id,
constness,
movability,
decl,
Expand All @@ -160,7 +159,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
binder: &ClosureBinder,
capture_clause: CaptureBy,
closure_id: NodeId,
closure_hir_id: HirId,
constness: Const,
movability: Movability,
decl: &FnDecl,
Expand All @@ -171,7 +169,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let closure_def_id = self.local_def_id(closure_id);
let (binder_clause, generic_params) = self.lower_closure_binder(binder);

let ((body_id, closure_kind), move_expr_state) =
let (((params, body_id), closure_kind), move_expr_state) =
self.with_new_scopes(fn_decl_span, move |this| {
let mut coroutine_kind = find_attr!(
attrs,
Expand Down Expand Up @@ -207,14 +205,7 @@ 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,
closure_hir_id,
FnDeclKind::Closure,
None,
DiscardParams::No,
);
let fn_decl = self.lower_fn_decl(decl, closure_id, FnDeclKind::Closure, None, true, params);

let c = self.arena.alloc(hir::Closure {
def_id: closure_def_id,
Expand Down Expand Up @@ -310,15 +301,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
};

let body = self.with_new_scopes(fn_decl_span, |this| {
let inner_decl =
FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };

let (parameters, body) = self.with_new_scopes(fn_decl_span, |this| {
// Transform `async |x: u8| -> X { ... }` into
// `|x: u8| || -> X { ... }`.
let body_id = this.lower_body(|this| {
let body_id = this.lower_body_with_params(|this| {
let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments(
&inner_decl,
&decl,
|this| this.with_new_scopes(fn_decl_span, |this| this.lower_expr_mut(body)),
fn_decl_span,
body.span,
Expand All @@ -337,14 +325,8 @@ 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(
&decl,
closure_id,
closure_hir_id,
FnDeclKind::Closure,
None,
DiscardParams::No,
);
let fn_decl =
self.lower_fn_decl(&decl, closure_id, FnDeclKind::Closure, None, true, parameters);

if let Const::Yes(span) = constness {
self.dcx().span_err(span, "const coroutines are not supported");
Expand Down
Loading
Loading