syntax: revert ast::AsyncArgument
and associated changes.
Here follows the main reverts applied in order to make this commit: Revert "Rollup merge of #60676 - davidtwco:issue-60674, r=cramertj" This reverts commit45b09453db
, reversing changes made tof6df1f6c30
. Revert "Rollup merge of #60437 - davidtwco:issue-60236, r=nikomatsakis" This reverts commit16939a50ea
, reversing changes made to12bf981552
. Revert "Rollup merge of #59823 - davidtwco:issue-54716, r=cramertj" This reverts commit62d1574876
, reversing changes made to4eff8526a7
.
This commit is contained in:
parent
c57ed9d947
commit
d0c78dd7aa
15 changed files with 108 additions and 520 deletions
|
@ -465,32 +465,6 @@ impl<'a> LoweringContext<'a> {
|
||||||
visit::walk_pat(self, p)
|
visit::walk_pat(self, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_fn(&mut self, fk: visit::FnKind<'lcx>, fd: &'lcx FnDecl, s: Span, _: NodeId) {
|
|
||||||
if fk.header().map(|h| h.asyncness.node.is_async()).unwrap_or(false) {
|
|
||||||
// Don't visit the original pattern for async functions as it will be
|
|
||||||
// replaced.
|
|
||||||
for arg in &fd.inputs {
|
|
||||||
if let ArgSource::AsyncFn(pat) = &arg.source { self.visit_pat(pat); }
|
|
||||||
self.visit_ty(&arg.ty)
|
|
||||||
}
|
|
||||||
self.visit_fn_ret_ty(&fd.output);
|
|
||||||
|
|
||||||
match fk {
|
|
||||||
visit::FnKind::ItemFn(_, decl, _, body) => {
|
|
||||||
self.visit_fn_header(decl);
|
|
||||||
self.visit_block(body)
|
|
||||||
},
|
|
||||||
visit::FnKind::Method(_, sig, _, body) => {
|
|
||||||
self.visit_fn_header(&sig.header);
|
|
||||||
self.visit_block(body)
|
|
||||||
},
|
|
||||||
visit::FnKind::Closure(body) => self.visit_expr(body),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
visit::walk_fn(self, fk, fd, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_item(&mut self, item: &'lcx Item) {
|
fn visit_item(&mut self, item: &'lcx Item) {
|
||||||
let hir_id = self.lctx.allocate_hir_id_counter(item.id);
|
let hir_id = self.lctx.allocate_hir_id_counter(item.id);
|
||||||
|
|
||||||
|
@ -2266,17 +2240,10 @@ impl<'a> LoweringContext<'a> {
|
||||||
init: l.init.as_ref().map(|e| P(self.lower_expr(e))),
|
init: l.init.as_ref().map(|e| P(self.lower_expr(e))),
|
||||||
span: l.span,
|
span: l.span,
|
||||||
attrs: l.attrs.clone(),
|
attrs: l.attrs.clone(),
|
||||||
source: self.lower_local_source(l.source),
|
source: hir::LocalSource::Normal,
|
||||||
}, ids)
|
}, ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_local_source(&mut self, ls: LocalSource) -> hir::LocalSource {
|
|
||||||
match ls {
|
|
||||||
LocalSource::Normal => hir::LocalSource::Normal,
|
|
||||||
LocalSource::AsyncFn => hir::LocalSource::AsyncFn,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
|
fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
|
||||||
match m {
|
match m {
|
||||||
Mutability::Mutable => hir::MutMutable,
|
Mutability::Mutable => hir::MutMutable,
|
||||||
|
@ -2292,14 +2259,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
hir::Arg {
|
hir::Arg {
|
||||||
hir_id: self.lower_node_id(arg.id),
|
hir_id: self.lower_node_id(arg.id),
|
||||||
pat: self.lower_pat(&arg.pat),
|
pat: self.lower_pat(&arg.pat),
|
||||||
source: self.lower_arg_source(&arg.source),
|
source: hir::ArgSource::Normal,
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lower_arg_source(&mut self, source: &ArgSource) -> hir::ArgSource {
|
|
||||||
match source {
|
|
||||||
ArgSource::Normal => hir::ArgSource::Normal,
|
|
||||||
ArgSource::AsyncFn(pat) => hir::ArgSource::AsyncFn(self.lower_pat(pat)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3028,44 +2988,13 @@ impl<'a> LoweringContext<'a> {
|
||||||
fn lower_async_body(
|
fn lower_async_body(
|
||||||
&mut self,
|
&mut self,
|
||||||
decl: &FnDecl,
|
decl: &FnDecl,
|
||||||
asyncness: &IsAsync,
|
asyncness: IsAsync,
|
||||||
body: &Block,
|
body: &Block,
|
||||||
) -> hir::BodyId {
|
) -> hir::BodyId {
|
||||||
self.lower_body(Some(&decl), |this| {
|
self.lower_body(Some(&decl), |this| {
|
||||||
if let IsAsync::Async { closure_id, ref arguments, .. } = asyncness {
|
if let IsAsync::Async { closure_id, .. } = asyncness {
|
||||||
let mut body = body.clone();
|
|
||||||
|
|
||||||
// Async function arguments are lowered into the closure body so that they are
|
|
||||||
// captured and so that the drop order matches the equivalent non-async functions.
|
|
||||||
//
|
|
||||||
// async fn foo(<pattern>: <ty>, <pattern>: <ty>, <pattern>: <ty>) {
|
|
||||||
// async move {
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // ...becomes...
|
|
||||||
// fn foo(__arg0: <ty>, __arg1: <ty>, __arg2: <ty>) {
|
|
||||||
// async move {
|
|
||||||
// let __arg2 = __arg2;
|
|
||||||
// let <pattern> = __arg2;
|
|
||||||
// let __arg1 = __arg1;
|
|
||||||
// let <pattern> = __arg1;
|
|
||||||
// let __arg0 = __arg0;
|
|
||||||
// let <pattern> = __arg0;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// If `<pattern>` is a simple ident, then it is lowered to a single
|
|
||||||
// `let <pattern> = <pattern>;` statement as an optimization.
|
|
||||||
for a in arguments.iter().rev() {
|
|
||||||
if let Some(pat_stmt) = a.pat_stmt.clone() {
|
|
||||||
body.stmts.insert(0, pat_stmt);
|
|
||||||
}
|
|
||||||
body.stmts.insert(0, a.move_stmt.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let async_expr = this.make_async_expr(
|
let async_expr = this.make_async_expr(
|
||||||
CaptureBy::Value, *closure_id, None, body.span,
|
CaptureBy::Value, closure_id, None, body.span,
|
||||||
|this| {
|
|this| {
|
||||||
let body = this.lower_block(&body, false);
|
let body = this.lower_block(&body, false);
|
||||||
this.expr_block(body, ThinVec::new())
|
this.expr_block(body, ThinVec::new())
|
||||||
|
@ -3126,47 +3055,26 @@ impl<'a> LoweringContext<'a> {
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ItemKind::Fn(ref decl, ref header, ref generics, ref body) => {
|
ItemKind::Fn(ref decl, header, ref generics, ref body) => {
|
||||||
let fn_def_id = self.resolver.definitions().local_def_id(id);
|
let fn_def_id = self.resolver.definitions().local_def_id(id);
|
||||||
self.with_new_scopes(|this| {
|
self.with_new_scopes(|this| {
|
||||||
|
// Note: we don't need to change the return type from `T` to
|
||||||
|
// `impl Future<Output = T>` here because lower_body
|
||||||
|
// only cares about the input argument patterns in the function
|
||||||
|
// declaration (decl), not the return types.
|
||||||
|
let body_id = this.lower_async_body(decl, header.asyncness.node, body);
|
||||||
|
let (generics, fn_decl) = this.add_in_band_defs(
|
||||||
|
generics,
|
||||||
|
fn_def_id,
|
||||||
|
AnonymousLifetimeMode::PassThrough,
|
||||||
|
|this, idty| this.lower_fn_decl(
|
||||||
|
decl,
|
||||||
|
Some((fn_def_id, idty)),
|
||||||
|
true,
|
||||||
|
header.asyncness.node.opt_return_id()
|
||||||
|
),
|
||||||
|
);
|
||||||
this.current_item = Some(ident.span);
|
this.current_item = Some(ident.span);
|
||||||
let mut lower_fn = |decl: &FnDecl| {
|
|
||||||
// Note: we don't need to change the return type from `T` to
|
|
||||||
// `impl Future<Output = T>` here because lower_body
|
|
||||||
// only cares about the input argument patterns in the function
|
|
||||||
// declaration (decl), not the return types.
|
|
||||||
let body_id = this.lower_async_body(&decl, &header.asyncness.node, body);
|
|
||||||
|
|
||||||
let (generics, fn_decl) = this.add_in_band_defs(
|
|
||||||
generics,
|
|
||||||
fn_def_id,
|
|
||||||
AnonymousLifetimeMode::PassThrough,
|
|
||||||
|this, idty| this.lower_fn_decl(
|
|
||||||
&decl,
|
|
||||||
Some((fn_def_id, idty)),
|
|
||||||
true,
|
|
||||||
header.asyncness.node.opt_return_id()
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
(body_id, generics, fn_decl)
|
|
||||||
};
|
|
||||||
|
|
||||||
let (body_id, generics, fn_decl) = if let IsAsync::Async {
|
|
||||||
arguments, ..
|
|
||||||
} = &header.asyncness.node {
|
|
||||||
let mut decl = decl.clone();
|
|
||||||
// Replace the arguments of this async function with the generated
|
|
||||||
// arguments that will be moved into the closure.
|
|
||||||
for (i, a) in arguments.clone().drain(..).enumerate() {
|
|
||||||
if let Some(arg) = a.arg {
|
|
||||||
decl.inputs[i] = arg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lower_fn(&decl)
|
|
||||||
} else {
|
|
||||||
lower_fn(decl)
|
|
||||||
};
|
|
||||||
|
|
||||||
hir::ItemKind::Fn(
|
hir::ItemKind::Fn(
|
||||||
fn_decl,
|
fn_decl,
|
||||||
|
@ -3638,36 +3546,15 @@ impl<'a> LoweringContext<'a> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ImplItemKind::Method(ref sig, ref body) => {
|
ImplItemKind::Method(ref sig, ref body) => {
|
||||||
let mut lower_method = |sig: &MethodSig| {
|
let body_id = self.lower_async_body(&sig.decl, sig.header.asyncness.node, body);
|
||||||
let body_id = self.lower_async_body(
|
let impl_trait_return_allow = !self.is_in_trait_impl;
|
||||||
&sig.decl, &sig.header.asyncness.node, body
|
let (generics, sig) = self.lower_method_sig(
|
||||||
);
|
&i.generics,
|
||||||
let impl_trait_return_allow = !self.is_in_trait_impl;
|
sig,
|
||||||
let (generics, sig) = self.lower_method_sig(
|
impl_item_def_id,
|
||||||
&i.generics,
|
impl_trait_return_allow,
|
||||||
sig,
|
sig.header.asyncness.node.opt_return_id(),
|
||||||
impl_item_def_id,
|
);
|
||||||
impl_trait_return_allow,
|
|
||||||
sig.header.asyncness.node.opt_return_id(),
|
|
||||||
);
|
|
||||||
(body_id, generics, sig)
|
|
||||||
};
|
|
||||||
|
|
||||||
let (body_id, generics, sig) = if let IsAsync::Async {
|
|
||||||
ref arguments, ..
|
|
||||||
} = sig.header.asyncness.node {
|
|
||||||
let mut sig = sig.clone();
|
|
||||||
// Replace the arguments of this async function with the generated
|
|
||||||
// arguments that will be moved into the closure.
|
|
||||||
for (i, a) in arguments.clone().drain(..).enumerate() {
|
|
||||||
if let Some(arg) = a.arg {
|
|
||||||
sig.decl.inputs[i] = arg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lower_method(&sig)
|
|
||||||
} else {
|
|
||||||
lower_method(sig)
|
|
||||||
};
|
|
||||||
self.current_item = Some(i.span);
|
self.current_item = Some(i.span);
|
||||||
|
|
||||||
(generics, hir::ImplItemKind::Method(sig, body_id))
|
(generics, hir::ImplItemKind::Method(sig, body_id))
|
||||||
|
@ -3860,7 +3747,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
impl_trait_return_allow: bool,
|
impl_trait_return_allow: bool,
|
||||||
is_async: Option<NodeId>,
|
is_async: Option<NodeId>,
|
||||||
) -> (hir::Generics, hir::MethodSig) {
|
) -> (hir::Generics, hir::MethodSig) {
|
||||||
let header = self.lower_fn_header(&sig.header);
|
let header = self.lower_fn_header(sig.header);
|
||||||
let (generics, decl) = self.add_in_band_defs(
|
let (generics, decl) = self.add_in_band_defs(
|
||||||
generics,
|
generics,
|
||||||
fn_def_id,
|
fn_def_id,
|
||||||
|
@ -3882,10 +3769,10 @@ impl<'a> LoweringContext<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_fn_header(&mut self, h: &FnHeader) -> hir::FnHeader {
|
fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
|
||||||
hir::FnHeader {
|
hir::FnHeader {
|
||||||
unsafety: self.lower_unsafety(h.unsafety),
|
unsafety: self.lower_unsafety(h.unsafety),
|
||||||
asyncness: self.lower_asyncness(&h.asyncness.node),
|
asyncness: self.lower_asyncness(h.asyncness.node),
|
||||||
constness: self.lower_constness(h.constness),
|
constness: self.lower_constness(h.constness),
|
||||||
abi: h.abi,
|
abi: h.abi,
|
||||||
}
|
}
|
||||||
|
@ -3905,7 +3792,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_asyncness(&mut self, a: &IsAsync) -> hir::IsAsync {
|
fn lower_asyncness(&mut self, a: IsAsync) -> hir::IsAsync {
|
||||||
match a {
|
match a {
|
||||||
IsAsync::Async { .. } => hir::IsAsync::Async,
|
IsAsync::Async { .. } => hir::IsAsync::Async,
|
||||||
IsAsync::NotAsync => hir::IsAsync::NotAsync,
|
IsAsync::NotAsync => hir::IsAsync::NotAsync,
|
||||||
|
@ -4222,7 +4109,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
}
|
}
|
||||||
ExprKind::Await(_origin, ref expr) => self.lower_await(e.span, expr),
|
ExprKind::Await(_origin, ref expr) => self.lower_await(e.span, expr),
|
||||||
ExprKind::Closure(
|
ExprKind::Closure(
|
||||||
capture_clause, ref asyncness, movability, ref decl, ref body, fn_decl_span
|
capture_clause, asyncness, movability, ref decl, ref body, fn_decl_span
|
||||||
) => {
|
) => {
|
||||||
if let IsAsync::Async { closure_id, .. } = asyncness {
|
if let IsAsync::Async { closure_id, .. } = asyncness {
|
||||||
let outer_decl = FnDecl {
|
let outer_decl = FnDecl {
|
||||||
|
@ -4260,7 +4147,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
Some(&**ty)
|
Some(&**ty)
|
||||||
} else { None };
|
} else { None };
|
||||||
let async_body = this.make_async_expr(
|
let async_body = this.make_async_expr(
|
||||||
capture_clause, *closure_id, async_ret_ty, body.span,
|
capture_clause, closure_id, async_ret_ty, body.span,
|
||||||
|this| {
|
|this| {
|
||||||
this.with_new_scopes(|this| this.lower_expr(body))
|
this.with_new_scopes(|this| this.lower_expr(body))
|
||||||
});
|
});
|
||||||
|
|
|
@ -64,17 +64,16 @@ impl<'a> DefCollector<'a> {
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
name: Name,
|
name: Name,
|
||||||
span: Span,
|
span: Span,
|
||||||
header: &'a FnHeader,
|
header: &FnHeader,
|
||||||
generics: &'a Generics,
|
generics: &'a Generics,
|
||||||
decl: &'a FnDecl,
|
decl: &'a FnDecl,
|
||||||
body: &'a Block,
|
body: &'a Block,
|
||||||
) {
|
) {
|
||||||
let (closure_id, return_impl_trait_id, arguments) = match &header.asyncness.node {
|
let (closure_id, return_impl_trait_id) = match header.asyncness.node {
|
||||||
IsAsync::Async {
|
IsAsync::Async {
|
||||||
closure_id,
|
closure_id,
|
||||||
return_impl_trait_id,
|
return_impl_trait_id,
|
||||||
arguments,
|
} => (closure_id, return_impl_trait_id),
|
||||||
} => (closure_id, return_impl_trait_id, arguments),
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -83,38 +82,16 @@ impl<'a> DefCollector<'a> {
|
||||||
let fn_def_data = DefPathData::ValueNs(name.as_interned_str());
|
let fn_def_data = DefPathData::ValueNs(name.as_interned_str());
|
||||||
let fn_def = self.create_def(id, fn_def_data, span);
|
let fn_def = self.create_def(id, fn_def_data, span);
|
||||||
return self.with_parent(fn_def, |this| {
|
return self.with_parent(fn_def, |this| {
|
||||||
this.create_def(*return_impl_trait_id, DefPathData::ImplTrait, span);
|
this.create_def(return_impl_trait_id, DefPathData::ImplTrait, span);
|
||||||
|
|
||||||
visit::walk_generics(this, generics);
|
visit::walk_generics(this, generics);
|
||||||
|
visit::walk_fn_decl(this, decl);
|
||||||
// Walk the generated arguments for the `async fn`.
|
|
||||||
for (i, a) in arguments.iter().enumerate() {
|
|
||||||
use visit::Visitor;
|
|
||||||
if let Some(arg) = &a.arg {
|
|
||||||
this.visit_ty(&arg.ty);
|
|
||||||
} else {
|
|
||||||
this.visit_ty(&decl.inputs[i].ty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We do not invoke `walk_fn_decl` as this will walk the arguments that are being
|
|
||||||
// replaced.
|
|
||||||
visit::walk_fn_ret_ty(this, &decl.output);
|
|
||||||
|
|
||||||
let closure_def = this.create_def(
|
let closure_def = this.create_def(
|
||||||
*closure_id, DefPathData::ClosureExpr, span,
|
closure_id, DefPathData::ClosureExpr, span,
|
||||||
);
|
);
|
||||||
this.with_parent(closure_def, |this| {
|
this.with_parent(closure_def, |this| {
|
||||||
use visit::Visitor;
|
visit::walk_block(this, body);
|
||||||
// Walk each of the generated statements before the regular block body.
|
|
||||||
for a in arguments {
|
|
||||||
this.visit_stmt(&a.move_stmt);
|
|
||||||
if let Some(pat_stmt) = &a.pat_stmt {
|
|
||||||
this.visit_stmt(&pat_stmt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
visit::walk_block(this, &body);
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -302,7 +279,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||||
|
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id),
|
ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id),
|
||||||
ExprKind::Closure(_, ref asyncness, ..) => {
|
ExprKind::Closure(_, asyncness, ..) => {
|
||||||
let closure_def = self.create_def(expr.id,
|
let closure_def = self.create_def(expr.id,
|
||||||
DefPathData::ClosureExpr,
|
DefPathData::ClosureExpr,
|
||||||
expr.span);
|
expr.span);
|
||||||
|
@ -311,7 +288,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||||
// Async closures desugar to closures inside of closures, so
|
// Async closures desugar to closures inside of closures, so
|
||||||
// we must create two defs.
|
// we must create two defs.
|
||||||
if let IsAsync::Async { closure_id, .. } = asyncness {
|
if let IsAsync::Async { closure_id, .. } = asyncness {
|
||||||
let async_def = self.create_def(*closure_id,
|
let async_def = self.create_def(closure_id,
|
||||||
DefPathData::ClosureExpr,
|
DefPathData::ClosureExpr,
|
||||||
expr.span);
|
expr.span);
|
||||||
self.parent_def = Some(async_def);
|
self.parent_def = Some(async_def);
|
||||||
|
|
|
@ -1335,30 +1335,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
|
||||||
|
|
||||||
run_early_pass!(self, check_mac, mac);
|
run_early_pass!(self, check_mac, mac);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_fn_header(&mut self, header: &'a ast::FnHeader) {
|
|
||||||
// Unlike in HIR lowering and name resolution, the `AsyncArgument` statements are not added
|
|
||||||
// to the function body and the arguments do not replace those in the declaration. They are
|
|
||||||
// still visited manually here so that buffered lints can be emitted.
|
|
||||||
if let ast::IsAsync::Async { ref arguments, .. } = header.asyncness.node {
|
|
||||||
for a in arguments {
|
|
||||||
// Visit the argument..
|
|
||||||
if let Some(arg) = &a.arg {
|
|
||||||
self.visit_pat(&arg.pat);
|
|
||||||
if let ast::ArgSource::AsyncFn(pat) = &arg.source {
|
|
||||||
self.visit_pat(pat);
|
|
||||||
}
|
|
||||||
self.visit_ty(&arg.ty);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ..and the statement.
|
|
||||||
self.visit_stmt(&a.move_stmt);
|
|
||||||
if let Some(pat_stmt) = &a.pat_stmt {
|
|
||||||
self.visit_stmt(&pat_stmt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LateLintPassObjects<'a> {
|
struct LateLintPassObjects<'a> {
|
||||||
|
|
|
@ -222,7 +222,7 @@ impl<'a> AstValidator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_trait_fn_not_async(&self, span: Span, asyncness: &IsAsync) {
|
fn check_trait_fn_not_async(&self, span: Span, asyncness: IsAsync) {
|
||||||
if asyncness.is_async() {
|
if asyncness.is_async() {
|
||||||
struct_span_err!(self.session, span, E0706,
|
struct_span_err!(self.session, span, E0706,
|
||||||
"trait fns cannot be declared `async`").emit()
|
"trait fns cannot be declared `async`").emit()
|
||||||
|
@ -561,7 +561,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
self.invalid_visibility(&impl_item.vis, None);
|
self.invalid_visibility(&impl_item.vis, None);
|
||||||
if let ImplItemKind::Method(ref sig, _) = impl_item.node {
|
if let ImplItemKind::Method(ref sig, _) = impl_item.node {
|
||||||
self.check_trait_fn_not_const(sig.header.constness);
|
self.check_trait_fn_not_const(sig.header.constness);
|
||||||
self.check_trait_fn_not_async(impl_item.span, &sig.header.asyncness.node);
|
self.check_trait_fn_not_async(impl_item.span, sig.header.asyncness.node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -633,7 +633,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
self.no_questions_in_bounds(bounds, "supertraits", true);
|
self.no_questions_in_bounds(bounds, "supertraits", true);
|
||||||
for trait_item in trait_items {
|
for trait_item in trait_items {
|
||||||
if let TraitItemKind::Method(ref sig, ref block) = trait_item.node {
|
if let TraitItemKind::Method(ref sig, ref block) = trait_item.node {
|
||||||
self.check_trait_fn_not_async(trait_item.span, &sig.header.asyncness.node);
|
self.check_trait_fn_not_async(trait_item.span, sig.header.asyncness.node);
|
||||||
self.check_trait_fn_not_const(sig.header.constness);
|
self.check_trait_fn_not_const(sig.header.constness);
|
||||||
if block.is_none() {
|
if block.is_none() {
|
||||||
self.check_decl_no_pat(&sig.decl, |span, mut_ident| {
|
self.check_decl_no_pat(&sig.decl, |span, mut_ident| {
|
||||||
|
|
|
@ -855,15 +855,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
|
||||||
_: NodeId)
|
_: NodeId)
|
||||||
{
|
{
|
||||||
debug!("(resolving function) entering function");
|
debug!("(resolving function) entering function");
|
||||||
let (rib_kind, asyncness) = match function_kind {
|
let rib_kind = match function_kind {
|
||||||
FnKind::ItemFn(_, ref header, ..) =>
|
FnKind::ItemFn(..) => FnItemRibKind,
|
||||||
(FnItemRibKind, &header.asyncness.node),
|
FnKind::Method(..) => AssocItemRibKind,
|
||||||
FnKind::Method(_, ref sig, _, _) =>
|
FnKind::Closure(_) => NormalRibKind,
|
||||||
(AssocItemRibKind, &sig.header.asyncness.node),
|
|
||||||
FnKind::Closure(_) =>
|
|
||||||
// Async closures aren't resolved through `visit_fn`-- they're
|
|
||||||
// processed separately
|
|
||||||
(NormalRibKind, &IsAsync::NotAsync),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a value rib for the function.
|
// Create a value rib for the function.
|
||||||
|
@ -874,45 +869,20 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
|
||||||
|
|
||||||
// Add each argument to the rib.
|
// Add each argument to the rib.
|
||||||
let mut bindings_list = FxHashMap::default();
|
let mut bindings_list = FxHashMap::default();
|
||||||
let mut add_argument = |argument: &ast::Arg| {
|
for argument in &declaration.inputs {
|
||||||
self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list);
|
self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list);
|
||||||
|
|
||||||
self.visit_ty(&argument.ty);
|
self.visit_ty(&argument.ty);
|
||||||
|
|
||||||
debug!("(resolving function) recorded argument");
|
debug!("(resolving function) recorded argument");
|
||||||
};
|
|
||||||
|
|
||||||
// Walk the generated async arguments if this is an `async fn`, otherwise walk the
|
|
||||||
// normal arguments.
|
|
||||||
if let IsAsync::Async { ref arguments, .. } = asyncness {
|
|
||||||
for (i, a) in arguments.iter().enumerate() {
|
|
||||||
if let Some(arg) = &a.arg {
|
|
||||||
add_argument(&arg);
|
|
||||||
} else {
|
|
||||||
add_argument(&declaration.inputs[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for a in &declaration.inputs { add_argument(a); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
visit::walk_fn_ret_ty(self, &declaration.output);
|
visit::walk_fn_ret_ty(self, &declaration.output);
|
||||||
|
|
||||||
// Resolve the function body, potentially inside the body of an async closure
|
// Resolve the function body, potentially inside the body of an async closure
|
||||||
match function_kind {
|
match function_kind {
|
||||||
FnKind::ItemFn(.., body) | FnKind::Method(.., body) => {
|
FnKind::ItemFn(.., body) |
|
||||||
if let IsAsync::Async { ref arguments, .. } = asyncness {
|
FnKind::Method(.., body) => {
|
||||||
let mut body = body.clone();
|
self.visit_block(body);
|
||||||
// Insert the generated statements into the body before attempting to
|
|
||||||
// resolve names.
|
|
||||||
for a in arguments.iter().rev() {
|
|
||||||
if let Some(pat_stmt) = a.pat_stmt.clone() {
|
|
||||||
body.stmts.insert(0, pat_stmt);
|
|
||||||
}
|
|
||||||
body.stmts.insert(0, a.move_stmt.clone());
|
|
||||||
}
|
|
||||||
self.visit_block(&body);
|
|
||||||
} else {
|
|
||||||
self.visit_block(body);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
FnKind::Closure(body) => {
|
FnKind::Closure(body) => {
|
||||||
self.visit_expr(body);
|
self.visit_expr(body);
|
||||||
|
@ -4178,7 +4148,7 @@ impl<'a> Resolver<'a> {
|
||||||
let add_module_candidates = |module: Module<'_>, names: &mut Vec<TypoSuggestion>| {
|
let add_module_candidates = |module: Module<'_>, names: &mut Vec<TypoSuggestion>| {
|
||||||
for (&(ident, _), resolution) in module.resolutions.borrow().iter() {
|
for (&(ident, _), resolution) in module.resolutions.borrow().iter() {
|
||||||
if let Some(binding) = resolution.borrow().binding {
|
if let Some(binding) = resolution.borrow().binding {
|
||||||
if !ident.is_gensymed() && filter_fn(binding.res()) {
|
if filter_fn(binding.res()) {
|
||||||
names.push(TypoSuggestion {
|
names.push(TypoSuggestion {
|
||||||
candidate: ident.name,
|
candidate: ident.name,
|
||||||
article: binding.res().article(),
|
article: binding.res().article(),
|
||||||
|
@ -4196,7 +4166,7 @@ impl<'a> Resolver<'a> {
|
||||||
for rib in self.ribs[ns].iter().rev() {
|
for rib in self.ribs[ns].iter().rev() {
|
||||||
// Locals and type parameters
|
// Locals and type parameters
|
||||||
for (ident, &res) in &rib.bindings {
|
for (ident, &res) in &rib.bindings {
|
||||||
if !ident.is_gensymed() && filter_fn(res) {
|
if filter_fn(res) {
|
||||||
names.push(TypoSuggestion {
|
names.push(TypoSuggestion {
|
||||||
candidate: ident.name,
|
candidate: ident.name,
|
||||||
article: res.article(),
|
article: res.article(),
|
||||||
|
@ -4226,7 +4196,7 @@ impl<'a> Resolver<'a> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if !ident.is_gensymed() && filter_fn(crate_mod) {
|
if filter_fn(crate_mod) {
|
||||||
Some(TypoSuggestion {
|
Some(TypoSuggestion {
|
||||||
candidate: ident.name,
|
candidate: ident.name,
|
||||||
article: "a",
|
article: "a",
|
||||||
|
@ -4249,15 +4219,13 @@ impl<'a> Resolver<'a> {
|
||||||
// Add primitive types to the mix
|
// Add primitive types to the mix
|
||||||
if filter_fn(Res::PrimTy(Bool)) {
|
if filter_fn(Res::PrimTy(Bool)) {
|
||||||
names.extend(
|
names.extend(
|
||||||
self.primitive_type_table.primitive_types
|
self.primitive_type_table.primitive_types.iter().map(|(name, _)| {
|
||||||
.iter()
|
TypoSuggestion {
|
||||||
.map(|(name, _)| {
|
candidate: *name,
|
||||||
TypoSuggestion {
|
article: "a",
|
||||||
candidate: *name,
|
kind: "primitive type",
|
||||||
article: "a",
|
}
|
||||||
kind: "primitive type",
|
})
|
||||||
}
|
|
||||||
})
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -374,7 +374,7 @@ impl Sig for ast::Item {
|
||||||
|
|
||||||
Ok(extend_sig(ty, text, defs, vec![]))
|
Ok(extend_sig(ty, text, defs, vec![]))
|
||||||
}
|
}
|
||||||
ast::ItemKind::Fn(ref decl, ref header, ref generics, _) => {
|
ast::ItemKind::Fn(ref decl, header, ref generics, _) => {
|
||||||
let mut text = String::new();
|
let mut text = String::new();
|
||||||
if header.constness.node == ast::Constness::Const {
|
if header.constness.node == ast::Constness::Const {
|
||||||
text.push_str("const ");
|
text.push_str("const ");
|
||||||
|
|
|
@ -879,17 +879,6 @@ pub struct Local {
|
||||||
pub id: NodeId,
|
pub id: NodeId,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub attrs: ThinVec<Attribute>,
|
pub attrs: ThinVec<Attribute>,
|
||||||
/// Origin of this local variable.
|
|
||||||
pub source: LocalSource,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
|
|
||||||
pub enum LocalSource {
|
|
||||||
/// Local was parsed from source.
|
|
||||||
Normal,
|
|
||||||
/// Within `ast::IsAsync::Async`, a local is generated that will contain the moved arguments
|
|
||||||
/// of an `async fn`.
|
|
||||||
AsyncFn,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An arm of a 'match'.
|
/// An arm of a 'match'.
|
||||||
|
@ -1770,16 +1759,6 @@ pub struct Arg {
|
||||||
pub ty: P<Ty>,
|
pub ty: P<Ty>,
|
||||||
pub pat: P<Pat>,
|
pub pat: P<Pat>,
|
||||||
pub id: NodeId,
|
pub id: NodeId,
|
||||||
pub source: ArgSource,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The source of an argument in a function header.
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
|
||||||
pub enum ArgSource {
|
|
||||||
/// Argument as written by the user.
|
|
||||||
Normal,
|
|
||||||
/// Argument from `async fn` lowering, contains the original binding pattern.
|
|
||||||
AsyncFn(P<Pat>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Alternative representation for `Arg`s describing `self` parameter of methods.
|
/// Alternative representation for `Arg`s describing `self` parameter of methods.
|
||||||
|
@ -1839,7 +1818,6 @@ impl Arg {
|
||||||
}),
|
}),
|
||||||
ty,
|
ty,
|
||||||
id: DUMMY_NODE_ID,
|
id: DUMMY_NODE_ID,
|
||||||
source: ArgSource::Normal,
|
|
||||||
};
|
};
|
||||||
match eself.node {
|
match eself.node {
|
||||||
SelfKind::Explicit(ty, mutbl) => arg(mutbl, ty),
|
SelfKind::Explicit(ty, mutbl) => arg(mutbl, ty),
|
||||||
|
@ -1894,39 +1872,18 @@ pub enum Unsafety {
|
||||||
Normal,
|
Normal,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||||
pub struct AsyncArgument {
|
|
||||||
/// `__arg0`
|
|
||||||
pub ident: Ident,
|
|
||||||
/// `__arg0: <ty>` argument to replace existing function argument `<pat>: <ty>`. Only if
|
|
||||||
/// argument is not a simple binding.
|
|
||||||
pub arg: Option<Arg>,
|
|
||||||
/// `let __arg0 = __arg0;` statement to be inserted at the start of the block.
|
|
||||||
pub move_stmt: Stmt,
|
|
||||||
/// `let <pat> = __arg0;` statement to be inserted at the start of the block, after matching
|
|
||||||
/// move statement. Only if argument is not a simple binding.
|
|
||||||
pub pat_stmt: Option<Stmt>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
|
||||||
pub enum IsAsync {
|
pub enum IsAsync {
|
||||||
Async {
|
Async {
|
||||||
closure_id: NodeId,
|
closure_id: NodeId,
|
||||||
return_impl_trait_id: NodeId,
|
return_impl_trait_id: NodeId,
|
||||||
/// This field stores the arguments and statements that are used in HIR lowering to
|
|
||||||
/// ensure that `async fn` arguments are dropped at the correct time.
|
|
||||||
///
|
|
||||||
/// The argument and statements here are generated at parse time as they are required in
|
|
||||||
/// both the hir lowering, def collection and name resolution and this stops them needing
|
|
||||||
/// to be created in each place.
|
|
||||||
arguments: Vec<AsyncArgument>,
|
|
||||||
},
|
},
|
||||||
NotAsync,
|
NotAsync,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IsAsync {
|
impl IsAsync {
|
||||||
pub fn is_async(&self) -> bool {
|
pub fn is_async(self) -> bool {
|
||||||
if let IsAsync::Async { .. } = *self {
|
if let IsAsync::Async { .. } = self {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -1934,12 +1891,12 @@ impl IsAsync {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// In ths case this is an `async` return, the `NodeId` for the generated `impl Trait` item.
|
/// In ths case this is an `async` return, the `NodeId` for the generated `impl Trait` item.
|
||||||
pub fn opt_return_id(&self) -> Option<NodeId> {
|
pub fn opt_return_id(self) -> Option<NodeId> {
|
||||||
match self {
|
match self {
|
||||||
IsAsync::Async {
|
IsAsync::Async {
|
||||||
return_impl_trait_id,
|
return_impl_trait_id,
|
||||||
..
|
..
|
||||||
} => Some(*return_impl_trait_id),
|
} => Some(return_impl_trait_id),
|
||||||
IsAsync::NotAsync => None,
|
IsAsync::NotAsync => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2279,7 +2236,7 @@ impl Item {
|
||||||
///
|
///
|
||||||
/// All the information between the visibility and the name of the function is
|
/// All the information between the visibility and the name of the function is
|
||||||
/// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`).
|
/// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`).
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
|
||||||
pub struct FnHeader {
|
pub struct FnHeader {
|
||||||
pub unsafety: Unsafety,
|
pub unsafety: Unsafety,
|
||||||
pub asyncness: Spanned<IsAsync>,
|
pub asyncness: Spanned<IsAsync>,
|
||||||
|
|
|
@ -516,7 +516,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
span: sp,
|
span: sp,
|
||||||
attrs: ThinVec::new(),
|
attrs: ThinVec::new(),
|
||||||
source: ast::LocalSource::Normal,
|
|
||||||
});
|
});
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
@ -545,7 +544,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
span: sp,
|
span: sp,
|
||||||
attrs: ThinVec::new(),
|
attrs: ThinVec::new(),
|
||||||
source: ast::LocalSource::Normal,
|
|
||||||
});
|
});
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
@ -563,7 +561,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
span,
|
span,
|
||||||
attrs: ThinVec::new(),
|
attrs: ThinVec::new(),
|
||||||
source: ast::LocalSource::Normal,
|
|
||||||
});
|
});
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
@ -971,8 +968,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
ast::Arg {
|
ast::Arg {
|
||||||
ty,
|
ty,
|
||||||
pat: arg_pat,
|
pat: arg_pat,
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID
|
||||||
source: ast::ArgSource::Normal,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,13 +101,6 @@ impl<'a, 'b> PlaceholderExpander<'a, 'b> {
|
||||||
fn remove(&mut self, id: ast::NodeId) -> AstFragment {
|
fn remove(&mut self, id: ast::NodeId) -> AstFragment {
|
||||||
self.expanded_fragments.remove(&id).unwrap()
|
self.expanded_fragments.remove(&id).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_id(&mut self, id: &mut ast::NodeId) {
|
|
||||||
if self.monotonic {
|
|
||||||
assert_eq!(*id, ast::DUMMY_NODE_ID);
|
|
||||||
*id = self.cx.resolver.next_node_id()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> {
|
impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> {
|
||||||
|
@ -189,19 +182,9 @@ impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> {
|
||||||
noop_visit_block(block, self);
|
noop_visit_block(block, self);
|
||||||
|
|
||||||
for stmt in block.stmts.iter_mut() {
|
for stmt in block.stmts.iter_mut() {
|
||||||
self.next_id(&mut stmt.id);
|
if self.monotonic {
|
||||||
}
|
assert_eq!(stmt.id, ast::DUMMY_NODE_ID);
|
||||||
}
|
stmt.id = self.cx.resolver.next_node_id();
|
||||||
|
|
||||||
fn visit_asyncness(&mut self, a: &mut ast::IsAsync) {
|
|
||||||
noop_visit_asyncness(a, self);
|
|
||||||
|
|
||||||
if let ast::IsAsync::Async { ref mut arguments, .. } = a {
|
|
||||||
for argument in arguments.iter_mut() {
|
|
||||||
self.next_id(&mut argument.move_stmt.id);
|
|
||||||
if let Some(ref mut pat_stmt) = &mut argument.pat_stmt {
|
|
||||||
self.next_id(&mut pat_stmt.id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,10 +207,6 @@ pub trait MutVisitor: Sized {
|
||||||
noop_visit_local(l, self);
|
noop_visit_local(l, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_local_source(&mut self, l: &mut LocalSource) {
|
|
||||||
noop_visit_local_source(l, self);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_mac(&mut self, _mac: &mut Mac) {
|
fn visit_mac(&mut self, _mac: &mut Mac) {
|
||||||
panic!("visit_mac disabled by default");
|
panic!("visit_mac disabled by default");
|
||||||
// N.B., see note about macros above. If you really want a visitor that
|
// N.B., see note about macros above. If you really want a visitor that
|
||||||
|
@ -234,10 +230,6 @@ pub trait MutVisitor: Sized {
|
||||||
noop_visit_arg(a, self);
|
noop_visit_arg(a, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_arg_source(&mut self, a: &mut ArgSource) {
|
|
||||||
noop_visit_arg_source(a, self);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_generics(&mut self, generics: &mut Generics) {
|
fn visit_generics(&mut self, generics: &mut Generics) {
|
||||||
noop_visit_generics(generics, self);
|
noop_visit_generics(generics, self);
|
||||||
}
|
}
|
||||||
|
@ -522,17 +514,13 @@ pub fn noop_visit_parenthesized_parameter_data<T: MutVisitor>(args: &mut Parenth
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) {
|
pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) {
|
||||||
let Local { id, pat, ty, init, span, attrs, source } = local.deref_mut();
|
let Local { id, pat, ty, init, span, attrs } = local.deref_mut();
|
||||||
vis.visit_id(id);
|
vis.visit_id(id);
|
||||||
vis.visit_pat(pat);
|
vis.visit_pat(pat);
|
||||||
visit_opt(ty, |ty| vis.visit_ty(ty));
|
visit_opt(ty, |ty| vis.visit_ty(ty));
|
||||||
visit_opt(init, |init| vis.visit_expr(init));
|
visit_opt(init, |init| vis.visit_expr(init));
|
||||||
vis.visit_span(span);
|
vis.visit_span(span);
|
||||||
visit_thin_attrs(attrs, vis);
|
visit_thin_attrs(attrs, vis);
|
||||||
vis.visit_local_source(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn noop_visit_local_source<T: MutVisitor>(_local_source: &mut LocalSource, _vis: &mut T) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
|
pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
|
||||||
|
@ -571,18 +559,10 @@ pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) {
|
||||||
vis.visit_span(span);
|
vis.visit_span(span);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn noop_visit_arg<T: MutVisitor>(Arg { id, pat, ty, source }: &mut Arg, vis: &mut T) {
|
pub fn noop_visit_arg<T: MutVisitor>(Arg { id, pat, ty }: &mut Arg, vis: &mut T) {
|
||||||
vis.visit_id(id);
|
vis.visit_id(id);
|
||||||
vis.visit_pat(pat);
|
vis.visit_pat(pat);
|
||||||
vis.visit_ty(ty);
|
vis.visit_ty(ty);
|
||||||
vis.visit_arg_source(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn noop_visit_arg_source<T: MutVisitor>(source: &mut ArgSource, vis: &mut T) {
|
|
||||||
match source {
|
|
||||||
ArgSource::Normal => {},
|
|
||||||
ArgSource::AsyncFn(pat) => vis.visit_pat(pat),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn noop_visit_tt<T: MutVisitor>(tt: &mut TokenTree, vis: &mut T) {
|
pub fn noop_visit_tt<T: MutVisitor>(tt: &mut TokenTree, vis: &mut T) {
|
||||||
|
@ -690,25 +670,9 @@ pub fn noop_visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis:
|
||||||
|
|
||||||
pub fn noop_visit_asyncness<T: MutVisitor>(asyncness: &mut IsAsync, vis: &mut T) {
|
pub fn noop_visit_asyncness<T: MutVisitor>(asyncness: &mut IsAsync, vis: &mut T) {
|
||||||
match asyncness {
|
match asyncness {
|
||||||
IsAsync::Async { closure_id, return_impl_trait_id, ref mut arguments } => {
|
IsAsync::Async { closure_id, return_impl_trait_id } => {
|
||||||
vis.visit_id(closure_id);
|
vis.visit_id(closure_id);
|
||||||
vis.visit_id(return_impl_trait_id);
|
vis.visit_id(return_impl_trait_id);
|
||||||
for AsyncArgument { ident, arg, pat_stmt, move_stmt } in arguments.iter_mut() {
|
|
||||||
vis.visit_ident(ident);
|
|
||||||
if let Some(arg) = arg {
|
|
||||||
vis.visit_arg(arg);
|
|
||||||
}
|
|
||||||
visit_clobber(move_stmt, |stmt| {
|
|
||||||
vis.flat_map_stmt(stmt)
|
|
||||||
.expect_one("expected visitor to produce exactly one item")
|
|
||||||
});
|
|
||||||
visit_opt(pat_stmt, |stmt| {
|
|
||||||
visit_clobber(stmt, |stmt| {
|
|
||||||
vis.flat_map_stmt(stmt)
|
|
||||||
.expect_one("expected visitor to produce exactly one item")
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
IsAsync::NotAsync => {}
|
IsAsync::NotAsync => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ crate fn dummy_arg(ident: Ident) -> Arg {
|
||||||
span: ident.span,
|
span: ident.span,
|
||||||
id: ast::DUMMY_NODE_ID
|
id: ast::DUMMY_NODE_ID
|
||||||
};
|
};
|
||||||
Arg { ty: P(ty), pat: pat, id: ast::DUMMY_NODE_ID, source: ast::ArgSource::Normal }
|
Arg { ty: P(ty), pat: pat, id: ast::DUMMY_NODE_ID }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
// ignore-tidy-filelength
|
// ignore-tidy-filelength
|
||||||
|
|
||||||
use crate::ast::{AngleBracketedArgs, AsyncArgument, ParenthesizedArgs, AttrStyle, BareFnTy};
|
use crate::ast::{AngleBracketedArgs, ParenthesizedArgs, AttrStyle, BareFnTy};
|
||||||
use crate::ast::{GenericBound, TraitBoundModifier};
|
use crate::ast::{GenericBound, TraitBoundModifier};
|
||||||
use crate::ast::Unsafety;
|
use crate::ast::Unsafety;
|
||||||
use crate::ast::{Mod, AnonConst, Arg, ArgSource, Arm, Guard, Attribute, BindingMode, TraitItemKind};
|
use crate::ast::{Mod, AnonConst, Arg, Arm, Guard, Attribute, BindingMode, TraitItemKind};
|
||||||
use crate::ast::Block;
|
use crate::ast::Block;
|
||||||
use crate::ast::{BlockCheckMode, CaptureBy, Movability};
|
use crate::ast::{BlockCheckMode, CaptureBy, Movability};
|
||||||
use crate::ast::{Constness, Crate};
|
use crate::ast::{Constness, Crate};
|
||||||
|
@ -16,7 +16,7 @@ use crate::ast::{GenericParam, GenericParamKind};
|
||||||
use crate::ast::GenericArg;
|
use crate::ast::GenericArg;
|
||||||
use crate::ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind};
|
use crate::ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind};
|
||||||
use crate::ast::{Label, Lifetime};
|
use crate::ast::{Label, Lifetime};
|
||||||
use crate::ast::{Local, LocalSource};
|
use crate::ast::Local;
|
||||||
use crate::ast::MacStmtStyle;
|
use crate::ast::MacStmtStyle;
|
||||||
use crate::ast::{Mac, Mac_, MacDelimiter};
|
use crate::ast::{Mac, Mac_, MacDelimiter};
|
||||||
use crate::ast::{MutTy, Mutability};
|
use crate::ast::{MutTy, Mutability};
|
||||||
|
@ -51,7 +51,7 @@ use crate::parse::diagnostics::{Error, dummy_arg};
|
||||||
|
|
||||||
use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
|
use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
|
||||||
use rustc_target::spec::abi::{self, Abi};
|
use rustc_target::spec::abi::{self, Abi};
|
||||||
use syntax_pos::{Span, BytePos, DUMMY_SP, FileName, hygiene::CompilerDesugaringKind};
|
use syntax_pos::{Span, BytePos, DUMMY_SP, FileName};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -1126,7 +1126,6 @@ impl<'a> Parser<'a> {
|
||||||
IsAsync::Async {
|
IsAsync::Async {
|
||||||
closure_id: ast::DUMMY_NODE_ID,
|
closure_id: ast::DUMMY_NODE_ID,
|
||||||
return_impl_trait_id: ast::DUMMY_NODE_ID,
|
return_impl_trait_id: ast::DUMMY_NODE_ID,
|
||||||
arguments: Vec::new(),
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
IsAsync::NotAsync
|
IsAsync::NotAsync
|
||||||
|
@ -1185,12 +1184,12 @@ impl<'a> Parser<'a> {
|
||||||
// trait item macro.
|
// trait item macro.
|
||||||
(Ident::invalid(), ast::TraitItemKind::Macro(mac), ast::Generics::default())
|
(Ident::invalid(), ast::TraitItemKind::Macro(mac), ast::Generics::default())
|
||||||
} else {
|
} else {
|
||||||
let (constness, unsafety, mut asyncness, abi) = self.parse_fn_front_matter()?;
|
let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
|
||||||
|
|
||||||
let ident = self.parse_ident()?;
|
let ident = self.parse_ident()?;
|
||||||
let mut generics = self.parse_generics()?;
|
let mut generics = self.parse_generics()?;
|
||||||
|
|
||||||
let mut decl = self.parse_fn_decl_with_self(|p: &mut Parser<'a>| {
|
let decl = self.parse_fn_decl_with_self(|p: &mut Parser<'a>| {
|
||||||
// This is somewhat dubious; We don't want to allow
|
// This is somewhat dubious; We don't want to allow
|
||||||
// argument names to be left off if there is a
|
// argument names to be left off if there is a
|
||||||
// definition...
|
// definition...
|
||||||
|
@ -1199,7 +1198,6 @@ impl<'a> Parser<'a> {
|
||||||
p.parse_arg_general(p.span.rust_2018(), true, false)
|
p.parse_arg_general(p.span.rust_2018(), true, false)
|
||||||
})?;
|
})?;
|
||||||
generics.where_clause = self.parse_where_clause()?;
|
generics.where_clause = self.parse_where_clause()?;
|
||||||
self.construct_async_arguments(&mut asyncness, &mut decl);
|
|
||||||
|
|
||||||
let sig = ast::MethodSig {
|
let sig = ast::MethodSig {
|
||||||
header: FnHeader {
|
header: FnHeader {
|
||||||
|
@ -1563,7 +1561,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Arg { ty, pat, id: ast::DUMMY_NODE_ID, source: ast::ArgSource::Normal })
|
Ok(Arg { ty, pat, id: ast::DUMMY_NODE_ID })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses an argument in a lambda header (e.g., `|arg, arg|`).
|
/// Parses an argument in a lambda header (e.g., `|arg, arg|`).
|
||||||
|
@ -1581,8 +1579,7 @@ impl<'a> Parser<'a> {
|
||||||
Ok(Arg {
|
Ok(Arg {
|
||||||
ty: t,
|
ty: t,
|
||||||
pat,
|
pat,
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID
|
||||||
source: ast::ArgSource::Normal,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4213,7 +4210,6 @@ impl<'a> Parser<'a> {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
span: lo.to(hi),
|
span: lo.to(hi),
|
||||||
attrs,
|
attrs,
|
||||||
source: LocalSource::Normal,
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5660,16 +5656,15 @@ impl<'a> Parser<'a> {
|
||||||
/// Parses an item-position function declaration.
|
/// Parses an item-position function declaration.
|
||||||
fn parse_item_fn(&mut self,
|
fn parse_item_fn(&mut self,
|
||||||
unsafety: Unsafety,
|
unsafety: Unsafety,
|
||||||
mut asyncness: Spanned<IsAsync>,
|
asyncness: Spanned<IsAsync>,
|
||||||
constness: Spanned<Constness>,
|
constness: Spanned<Constness>,
|
||||||
abi: Abi)
|
abi: Abi)
|
||||||
-> PResult<'a, ItemInfo> {
|
-> PResult<'a, ItemInfo> {
|
||||||
let (ident, mut generics) = self.parse_fn_header()?;
|
let (ident, mut generics) = self.parse_fn_header()?;
|
||||||
let allow_c_variadic = abi == Abi::C && unsafety == Unsafety::Unsafe;
|
let allow_c_variadic = abi == Abi::C && unsafety == Unsafety::Unsafe;
|
||||||
let mut decl = self.parse_fn_decl(allow_c_variadic)?;
|
let decl = self.parse_fn_decl(allow_c_variadic)?;
|
||||||
generics.where_clause = self.parse_where_clause()?;
|
generics.where_clause = self.parse_where_clause()?;
|
||||||
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
|
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
|
||||||
self.construct_async_arguments(&mut asyncness, &mut decl);
|
|
||||||
let header = FnHeader { unsafety, asyncness, constness, abi };
|
let header = FnHeader { unsafety, asyncness, constness, abi };
|
||||||
Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs)))
|
Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs)))
|
||||||
}
|
}
|
||||||
|
@ -5849,14 +5844,13 @@ impl<'a> Parser<'a> {
|
||||||
Ok((Ident::invalid(), vec![], ast::Generics::default(),
|
Ok((Ident::invalid(), vec![], ast::Generics::default(),
|
||||||
ast::ImplItemKind::Macro(mac)))
|
ast::ImplItemKind::Macro(mac)))
|
||||||
} else {
|
} else {
|
||||||
let (constness, unsafety, mut asyncness, abi) = self.parse_fn_front_matter()?;
|
let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
|
||||||
let ident = self.parse_ident()?;
|
let ident = self.parse_ident()?;
|
||||||
let mut generics = self.parse_generics()?;
|
let mut generics = self.parse_generics()?;
|
||||||
let mut decl = self.parse_fn_decl_with_self(|p| {
|
let decl = self.parse_fn_decl_with_self(|p| {
|
||||||
p.parse_arg_general(true, true, false)
|
p.parse_arg_general(true, true, false)
|
||||||
})?;
|
})?;
|
||||||
generics.where_clause = self.parse_where_clause()?;
|
generics.where_clause = self.parse_where_clause()?;
|
||||||
self.construct_async_arguments(&mut asyncness, &mut decl);
|
|
||||||
*at_end = true;
|
*at_end = true;
|
||||||
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
|
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
|
||||||
let header = ast::FnHeader { abi, unsafety, constness, asyncness };
|
let header = ast::FnHeader { abi, unsafety, constness, asyncness };
|
||||||
|
@ -7218,7 +7212,6 @@ impl<'a> Parser<'a> {
|
||||||
respan(async_span, IsAsync::Async {
|
respan(async_span, IsAsync::Async {
|
||||||
closure_id: ast::DUMMY_NODE_ID,
|
closure_id: ast::DUMMY_NODE_ID,
|
||||||
return_impl_trait_id: ast::DUMMY_NODE_ID,
|
return_impl_trait_id: ast::DUMMY_NODE_ID,
|
||||||
arguments: Vec::new(),
|
|
||||||
}),
|
}),
|
||||||
respan(fn_span, Constness::NotConst),
|
respan(fn_span, Constness::NotConst),
|
||||||
Abi::Rust)?;
|
Abi::Rust)?;
|
||||||
|
@ -7849,116 +7842,6 @@ impl<'a> Parser<'a> {
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
).emit();
|
).emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When lowering a `async fn` to the HIR, we need to move all of the arguments of the function
|
|
||||||
/// into the generated closure so that they are dropped when the future is polled and not when
|
|
||||||
/// it is created.
|
|
||||||
///
|
|
||||||
/// The arguments of the function are replaced in HIR lowering with the arguments created by
|
|
||||||
/// this function and the statements created here are inserted at the top of the closure body.
|
|
||||||
fn construct_async_arguments(&mut self, asyncness: &mut Spanned<IsAsync>, decl: &mut FnDecl) {
|
|
||||||
// FIXME(davidtwco): This function should really live in the HIR lowering but because
|
|
||||||
// the types constructed here need to be used in parts of resolve so that the correct
|
|
||||||
// locals are considered upvars, it is currently easier for it to live here in the parser,
|
|
||||||
// where it can be constructed once.
|
|
||||||
if let IsAsync::Async { ref mut arguments, .. } = asyncness.node {
|
|
||||||
for (index, input) in decl.inputs.iter_mut().enumerate() {
|
|
||||||
let id = ast::DUMMY_NODE_ID;
|
|
||||||
let span = input.pat.span;
|
|
||||||
let desugared_span = self.sess.source_map()
|
|
||||||
.mark_span_with_reason(CompilerDesugaringKind::Async, span, None);
|
|
||||||
|
|
||||||
// Construct a name for our temporary argument.
|
|
||||||
let name = format!("__arg{}", index);
|
|
||||||
let ident = Ident::from_str(&name).gensym();
|
|
||||||
|
|
||||||
// Check if this is a ident pattern, if so, we can optimize and avoid adding a
|
|
||||||
// `let <pat> = __argN;` statement, instead just adding a `let <pat> = <pat>;`
|
|
||||||
// statement.
|
|
||||||
let (binding_mode, ident, is_simple_pattern) = match input.pat.node {
|
|
||||||
PatKind::Ident(binding_mode @ BindingMode::ByValue(_), ident, _) => {
|
|
||||||
// Simple patterns like this don't have a generated argument, but they are
|
|
||||||
// moved into the closure with a statement, so any `mut` bindings on the
|
|
||||||
// argument will be unused. This binding mode can't be removed, because
|
|
||||||
// this would affect the input to procedural macros, but they can have
|
|
||||||
// their span marked as being the result of a compiler desugaring so
|
|
||||||
// that they aren't linted against.
|
|
||||||
input.pat.span = desugared_span;
|
|
||||||
|
|
||||||
(binding_mode, ident, true)
|
|
||||||
}
|
|
||||||
_ => (BindingMode::ByValue(Mutability::Mutable), ident, false),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Construct an argument representing `__argN: <ty>` to replace the argument of the
|
|
||||||
// async function if it isn't a simple pattern.
|
|
||||||
let arg = if is_simple_pattern {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(Arg {
|
|
||||||
ty: input.ty.clone(),
|
|
||||||
id,
|
|
||||||
pat: P(Pat {
|
|
||||||
id,
|
|
||||||
node: PatKind::Ident(
|
|
||||||
BindingMode::ByValue(Mutability::Immutable), ident, None,
|
|
||||||
),
|
|
||||||
span: desugared_span,
|
|
||||||
}),
|
|
||||||
source: ArgSource::AsyncFn(input.pat.clone()),
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
// Construct a `let __argN = __argN;` statement to insert at the top of the
|
|
||||||
// async closure. This makes sure that the argument is captured by the closure and
|
|
||||||
// that the drop order is correct.
|
|
||||||
let move_local = Local {
|
|
||||||
pat: P(Pat {
|
|
||||||
id,
|
|
||||||
node: PatKind::Ident(binding_mode, ident, None),
|
|
||||||
span: desugared_span,
|
|
||||||
}),
|
|
||||||
// We explicitly do not specify the type for this statement. When the user's
|
|
||||||
// argument type is `impl Trait` then this would require the
|
|
||||||
// `impl_trait_in_bindings` feature to also be present for that same type to
|
|
||||||
// be valid in this binding. At the time of writing (13 Mar 19),
|
|
||||||
// `impl_trait_in_bindings` is not stable.
|
|
||||||
ty: None,
|
|
||||||
init: Some(P(Expr {
|
|
||||||
id,
|
|
||||||
node: ExprKind::Path(None, ast::Path {
|
|
||||||
span,
|
|
||||||
segments: vec![PathSegment { ident, id, args: None }],
|
|
||||||
}),
|
|
||||||
span,
|
|
||||||
attrs: ThinVec::new(),
|
|
||||||
})),
|
|
||||||
id,
|
|
||||||
span,
|
|
||||||
attrs: ThinVec::new(),
|
|
||||||
source: LocalSource::AsyncFn,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Construct a `let <pat> = __argN;` statement to insert at the top of the
|
|
||||||
// async closure if this isn't a simple pattern.
|
|
||||||
let pat_stmt = if is_simple_pattern {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(Stmt {
|
|
||||||
id,
|
|
||||||
node: StmtKind::Local(P(Local {
|
|
||||||
pat: input.pat.clone(),
|
|
||||||
..move_local.clone()
|
|
||||||
})),
|
|
||||||
span,
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let move_stmt = Stmt { id, node: StmtKind::Local(P(move_local)), span };
|
|
||||||
arguments.push(AsyncArgument { ident, arg, pat_stmt, move_stmt });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, handler: &errors::Handler) {
|
pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, handler: &errors::Handler) {
|
||||||
|
|
|
@ -357,7 +357,7 @@ pub fn vis_to_string(v: &ast::Visibility) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fun_to_string(decl: &ast::FnDecl,
|
pub fn fun_to_string(decl: &ast::FnDecl,
|
||||||
header: &ast::FnHeader,
|
header: ast::FnHeader,
|
||||||
name: ast::Ident,
|
name: ast::Ident,
|
||||||
generics: &ast::Generics)
|
generics: &ast::Generics)
|
||||||
-> String {
|
-> String {
|
||||||
|
@ -1040,7 +1040,7 @@ impl<'a> State<'a> {
|
||||||
match item.node {
|
match item.node {
|
||||||
ast::ForeignItemKind::Fn(ref decl, ref generics) => {
|
ast::ForeignItemKind::Fn(ref decl, ref generics) => {
|
||||||
self.head("")?;
|
self.head("")?;
|
||||||
self.print_fn(decl, &ast::FnHeader::default(),
|
self.print_fn(decl, ast::FnHeader::default(),
|
||||||
Some(item.ident),
|
Some(item.ident),
|
||||||
generics, &item.vis)?;
|
generics, &item.vis)?;
|
||||||
self.end()?; // end head-ibox
|
self.end()?; // end head-ibox
|
||||||
|
@ -1170,7 +1170,7 @@ impl<'a> State<'a> {
|
||||||
self.s.word(";")?;
|
self.s.word(";")?;
|
||||||
self.end()?; // end the outer cbox
|
self.end()?; // end the outer cbox
|
||||||
}
|
}
|
||||||
ast::ItemKind::Fn(ref decl, ref header, ref param_names, ref body) => {
|
ast::ItemKind::Fn(ref decl, header, ref param_names, ref body) => {
|
||||||
self.head("")?;
|
self.head("")?;
|
||||||
self.print_fn(
|
self.print_fn(
|
||||||
decl,
|
decl,
|
||||||
|
@ -1522,7 +1522,7 @@ impl<'a> State<'a> {
|
||||||
vis: &ast::Visibility)
|
vis: &ast::Visibility)
|
||||||
-> io::Result<()> {
|
-> io::Result<()> {
|
||||||
self.print_fn(&m.decl,
|
self.print_fn(&m.decl,
|
||||||
&m.header,
|
m.header,
|
||||||
Some(ident),
|
Some(ident),
|
||||||
&generics,
|
&generics,
|
||||||
vis)
|
vis)
|
||||||
|
@ -2113,7 +2113,7 @@ impl<'a> State<'a> {
|
||||||
self.bclose_(expr.span, INDENT_UNIT)?;
|
self.bclose_(expr.span, INDENT_UNIT)?;
|
||||||
}
|
}
|
||||||
ast::ExprKind::Closure(
|
ast::ExprKind::Closure(
|
||||||
capture_clause, ref asyncness, movability, ref decl, ref body, _) => {
|
capture_clause, asyncness, movability, ref decl, ref body, _) => {
|
||||||
self.print_movability(movability)?;
|
self.print_movability(movability)?;
|
||||||
self.print_asyncness(asyncness)?;
|
self.print_asyncness(asyncness)?;
|
||||||
self.print_capture_clause(capture_clause)?;
|
self.print_capture_clause(capture_clause)?;
|
||||||
|
@ -2710,7 +2710,7 @@ impl<'a> State<'a> {
|
||||||
|
|
||||||
pub fn print_fn(&mut self,
|
pub fn print_fn(&mut self,
|
||||||
decl: &ast::FnDecl,
|
decl: &ast::FnDecl,
|
||||||
header: &ast::FnHeader,
|
header: ast::FnHeader,
|
||||||
name: Option<ast::Ident>,
|
name: Option<ast::Ident>,
|
||||||
generics: &ast::Generics,
|
generics: &ast::Generics,
|
||||||
vis: &ast::Visibility) -> io::Result<()> {
|
vis: &ast::Visibility) -> io::Result<()> {
|
||||||
|
@ -2765,7 +2765,8 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_asyncness(&mut self, asyncness: &ast::IsAsync) -> io::Result<()> {
|
pub fn print_asyncness(&mut self, asyncness: ast::IsAsync)
|
||||||
|
-> io::Result<()> {
|
||||||
if asyncness.is_async() {
|
if asyncness.is_async() {
|
||||||
self.word_nbsp("async")?;
|
self.word_nbsp("async")?;
|
||||||
}
|
}
|
||||||
|
@ -3037,7 +3038,7 @@ impl<'a> State<'a> {
|
||||||
span: syntax_pos::DUMMY_SP,
|
span: syntax_pos::DUMMY_SP,
|
||||||
};
|
};
|
||||||
self.print_fn(decl,
|
self.print_fn(decl,
|
||||||
&ast::FnHeader { unsafety, abi, ..ast::FnHeader::default() },
|
ast::FnHeader { unsafety, abi, ..ast::FnHeader::default() },
|
||||||
name,
|
name,
|
||||||
&generics,
|
&generics,
|
||||||
&source_map::dummy_spanned(ast::VisibilityKind::Inherited))?;
|
&source_map::dummy_spanned(ast::VisibilityKind::Inherited))?;
|
||||||
|
@ -3100,7 +3101,7 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_fn_header_info(&mut self,
|
pub fn print_fn_header_info(&mut self,
|
||||||
header: &ast::FnHeader,
|
header: ast::FnHeader,
|
||||||
vis: &ast::Visibility) -> io::Result<()> {
|
vis: &ast::Visibility) -> io::Result<()> {
|
||||||
self.s.word(visibility_qualified(vis, ""))?;
|
self.s.word(visibility_qualified(vis, ""))?;
|
||||||
|
|
||||||
|
@ -3109,7 +3110,7 @@ impl<'a> State<'a> {
|
||||||
ast::Constness::Const => self.word_nbsp("const")?
|
ast::Constness::Const => self.word_nbsp("const")?
|
||||||
}
|
}
|
||||||
|
|
||||||
self.print_asyncness(&header.asyncness.node)?;
|
self.print_asyncness(header.asyncness.node)?;
|
||||||
self.print_unsafety(header.unsafety)?;
|
self.print_unsafety(header.unsafety)?;
|
||||||
|
|
||||||
if header.abi != Abi::Rust {
|
if header.abi != Abi::Rust {
|
||||||
|
@ -3158,7 +3159,7 @@ mod tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
fun_to_string(
|
fun_to_string(
|
||||||
&decl,
|
&decl,
|
||||||
&ast::FnHeader {
|
ast::FnHeader {
|
||||||
unsafety: ast::Unsafety::Normal,
|
unsafety: ast::Unsafety::Normal,
|
||||||
constness: source_map::dummy_spanned(ast::Constness::NotConst),
|
constness: source_map::dummy_spanned(ast::Constness::NotConst),
|
||||||
asyncness: source_map::dummy_spanned(ast::IsAsync::NotAsync),
|
asyncness: source_map::dummy_spanned(ast::IsAsync::NotAsync),
|
||||||
|
|
|
@ -544,9 +544,6 @@ pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FunctionR
|
||||||
pub fn walk_fn_decl<'a, V: Visitor<'a>>(visitor: &mut V, function_declaration: &'a FnDecl) {
|
pub fn walk_fn_decl<'a, V: Visitor<'a>>(visitor: &mut V, function_declaration: &'a FnDecl) {
|
||||||
for argument in &function_declaration.inputs {
|
for argument in &function_declaration.inputs {
|
||||||
visitor.visit_pat(&argument.pat);
|
visitor.visit_pat(&argument.pat);
|
||||||
if let ArgSource::AsyncFn(pat) = &argument.source {
|
|
||||||
visitor.visit_pat(pat);
|
|
||||||
}
|
|
||||||
visitor.visit_ty(&argument.ty)
|
visitor.visit_ty(&argument.ty)
|
||||||
}
|
}
|
||||||
visitor.visit_fn_ret_ty(&function_declaration.output)
|
visitor.visit_fn_ret_ty(&function_declaration.output)
|
||||||
|
|
|
@ -129,7 +129,6 @@ fn stmt_let_undescore(cx: &mut ExtCtxt<'_>, sp: Span, expr: P<ast::Expr>) -> ast
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
span: sp,
|
span: sp,
|
||||||
attrs: ThinVec::new(),
|
attrs: ThinVec::new(),
|
||||||
source: ast::LocalSource::Normal,
|
|
||||||
});
|
});
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue