Async methods
This commit is contained in:
parent
d02631d3df
commit
d64e577fa3
8 changed files with 122 additions and 79 deletions
|
|
@ -2932,7 +2932,7 @@ impl<'a> LoweringContext<'a> {
|
|||
AnonymousLifetimeMode::PassThrough,
|
||||
|this| {
|
||||
hir::TraitItemKind::Method(
|
||||
this.lower_method_sig(sig, trait_item_def_id, false),
|
||||
this.lower_method_sig(sig, trait_item_def_id, false, false),
|
||||
hir::TraitMethod::Required(names),
|
||||
)
|
||||
},
|
||||
|
|
@ -2950,7 +2950,7 @@ impl<'a> LoweringContext<'a> {
|
|||
AnonymousLifetimeMode::PassThrough,
|
||||
|this| {
|
||||
hir::TraitItemKind::Method(
|
||||
this.lower_method_sig(sig, trait_item_def_id, false),
|
||||
this.lower_method_sig(sig, trait_item_def_id, false, false),
|
||||
hir::TraitMethod::Provided(body_id),
|
||||
)
|
||||
},
|
||||
|
|
@ -3021,8 +3021,18 @@ impl<'a> LoweringContext<'a> {
|
|||
}
|
||||
ImplItemKind::Method(ref sig, ref body) => {
|
||||
let body_id = self.lower_body(Some(&sig.decl), |this| {
|
||||
let body = this.lower_block(body, false);
|
||||
this.expr_block(body, ThinVec::new())
|
||||
if let IsAsync::Async(async_node_id) = sig.header.asyncness {
|
||||
let async_expr = this.make_async_expr(
|
||||
CaptureBy::Value, async_node_id, None,
|
||||
|this| {
|
||||
let body = this.lower_block(body, false);
|
||||
this.expr_block(body, ThinVec::new())
|
||||
});
|
||||
this.expr(body.span, async_expr, ThinVec::new())
|
||||
} else {
|
||||
let body = this.lower_block(body, false);
|
||||
this.expr_block(body, ThinVec::new())
|
||||
}
|
||||
});
|
||||
let impl_trait_return_allow = !self.is_in_trait_impl;
|
||||
|
||||
|
|
@ -3036,6 +3046,7 @@ impl<'a> LoweringContext<'a> {
|
|||
sig,
|
||||
impl_item_def_id,
|
||||
impl_trait_return_allow,
|
||||
sig.header.asyncness.is_async(),
|
||||
),
|
||||
body_id,
|
||||
)
|
||||
|
|
@ -3201,10 +3212,11 @@ impl<'a> LoweringContext<'a> {
|
|||
sig: &MethodSig,
|
||||
fn_def_id: DefId,
|
||||
impl_trait_return_allow: bool,
|
||||
is_async: bool,
|
||||
) -> hir::MethodSig {
|
||||
hir::MethodSig {
|
||||
header: self.lower_fn_header(sig.header),
|
||||
decl: self.lower_fn_decl(&sig.decl, Some(fn_def_id), impl_trait_return_allow, false),
|
||||
decl: self.lower_fn_decl(&sig.decl, Some(fn_def_id), impl_trait_return_allow, is_async),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,27 @@ impl<'a> DefCollector<'a> {
|
|||
self.parent_def = parent;
|
||||
}
|
||||
|
||||
fn visit_async_fn(
|
||||
&mut self,
|
||||
id: NodeId,
|
||||
async_node_id: NodeId,
|
||||
name: Name,
|
||||
span: Span,
|
||||
visit_fn: impl FnOnce(&mut DefCollector<'a>)
|
||||
) {
|
||||
// For async functions, we need to create their inner defs inside of a
|
||||
// closure to match their desugared representation.
|
||||
let fn_def_data = DefPathData::ValueNs(name.as_interned_str());
|
||||
let fn_def = self.create_def(id, fn_def_data, ITEM_LIKE_SPACE, span);
|
||||
return self.with_parent(fn_def, |this| {
|
||||
let closure_def = this.create_def(async_node_id,
|
||||
DefPathData::ClosureExpr,
|
||||
REGULAR_SPACE,
|
||||
span);
|
||||
this.with_parent(closure_def, visit_fn)
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_macro_invoc(&mut self, id: NodeId) {
|
||||
if let Some(ref mut visit) = self.visit_macro_invoc {
|
||||
visit(MacroInvocationData {
|
||||
|
|
@ -100,19 +121,13 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
|||
return visit::walk_item(self, i);
|
||||
}
|
||||
ItemKind::Fn(_, FnHeader { asyncness: IsAsync::Async(async_node_id), .. }, ..) => {
|
||||
// For async functions, we need to create their inner defs inside of a
|
||||
// closure to match their desugared representation.
|
||||
let fn_def_data = DefPathData::ValueNs(i.ident.name.as_interned_str());
|
||||
let fn_def = self.create_def(i.id, fn_def_data, ITEM_LIKE_SPACE, i.span);
|
||||
return self.with_parent(fn_def, |this| {
|
||||
let closure_def = this.create_def(async_node_id,
|
||||
DefPathData::ClosureExpr,
|
||||
REGULAR_SPACE,
|
||||
i.span);
|
||||
this.with_parent(closure_def, |this| {
|
||||
visit::walk_item(this, i);
|
||||
})
|
||||
});
|
||||
return self.visit_async_fn(
|
||||
i.id,
|
||||
async_node_id,
|
||||
i.ident.name,
|
||||
i.span,
|
||||
|this| visit::walk_item(this, i)
|
||||
)
|
||||
}
|
||||
ItemKind::Mod(..) => DefPathData::Module(i.ident.name.as_interned_str()),
|
||||
ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
|
||||
|
|
@ -212,6 +227,17 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
|||
|
||||
fn visit_impl_item(&mut self, ii: &'a ImplItem) {
|
||||
let def_data = match ii.node {
|
||||
ImplItemKind::Method(MethodSig {
|
||||
header: FnHeader { asyncness: IsAsync::Async(async_node_id), .. }, ..
|
||||
}, ..) => {
|
||||
return self.visit_async_fn(
|
||||
ii.id,
|
||||
async_node_id,
|
||||
ii.ident.name,
|
||||
ii.span,
|
||||
|this| visit::walk_impl_item(this, ii)
|
||||
)
|
||||
}
|
||||
ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
|
||||
DefPathData::ValueNs(ii.ident.name.as_interned_str()),
|
||||
ImplItemKind::Type(..) => DefPathData::AssocTypeInImpl(ii.ident.name.as_interned_str()),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue