Async closures
diff --git a/src/expr.rs b/src/expr.rs
index 3de219c..748f4a5 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -313,6 +313,7 @@
/// *This type is available if Syn is built with the `"full"` feature.*
pub Closure(ExprClosure #full {
pub attrs: Vec<Attribute>,
+ pub asyncness: Option<Token![async]>,
pub movability: Option<Token![static]>,
pub capture: Option<Token![move]>,
pub or1_token: Token![|],
@@ -2101,7 +2102,6 @@
#[cfg(feature = "full")]
named!(expr_closure(allow_struct: bool) -> Expr, do_parse!(
- begin: call!(verbatim::grab_cursor) >>
attrs: many0!(Attribute::parse_outer) >>
asyncness: option!(keyword!(async)) >>
movability: option!(cond_reduce!(asyncness.is_none(), keyword!(static))) >>
@@ -2125,27 +2125,17 @@
|
map!(ambiguous_expr!(allow_struct), |e| (ReturnType::Default, e))
) >>
- end: call!(verbatim::grab_cursor) >>
- ({
- if asyncness.is_some() {
- // TODO: include asyncness in ExprClosure
- // https://github.com/dtolnay/syn/issues/396
- Expr::Verbatim(ExprVerbatim {
- tts: verbatim::token_range(begin..end),
- })
- } else {
- Expr::Closure(ExprClosure {
- attrs: attrs,
- movability: movability,
- capture: capture,
- or1_token: or1,
- inputs: inputs,
- or2_token: or2,
- output: ret_and_body.0,
- body: Box::new(ret_and_body.1),
- })
- }
- })
+ (Expr::Closure(ExprClosure {
+ attrs: attrs,
+ asyncness: asyncness,
+ movability: movability,
+ capture: capture,
+ or1_token: or1,
+ inputs: inputs,
+ or2_token: or2,
+ output: ret_and_body.0,
+ body: Box::new(ret_and_body.1),
+ }))
));
#[cfg(feature = "full")]
@@ -3444,6 +3434,7 @@
impl ToTokens for ExprClosure {
fn to_tokens(&self, tokens: &mut TokenStream) {
outer_attrs_to_tokens(&self.attrs, tokens);
+ self.asyncness.to_tokens(tokens);
self.movability.to_tokens(tokens);
self.capture.to_tokens(tokens);
self.or1_token.to_tokens(tokens);
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index f73e64d..450aec9 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -1309,6 +1309,7 @@
pub fn fold_expr_closure<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprClosure) -> ExprClosure {
ExprClosure {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+ asyncness: (_i.asyncness).map(|it| Token)),
movability: (_i.movability).map(|it| Token ! [ static ](tokens_helper(_visitor, &it.span))),
capture: (_i.capture).map(|it| Token ! [ move ](tokens_helper(_visitor, &it.span))),
or1_token: Token ! [ | ](tokens_helper(_visitor, &_i.or1_token.spans)),
diff --git a/src/gen/visit.rs b/src/gen/visit.rs
index f3015be..f0bf8bf 100644
--- a/src/gen/visit.rs
+++ b/src/gen/visit.rs
@@ -1379,6 +1379,9 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
+ if let Some(ref it) = _i.asyncness {
+ tokens_helper(_visitor, &it.span)
+ };
if let Some(ref it) = _i.movability {
tokens_helper(_visitor, &it.span)
};
diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs
index 6f61765..16e1583 100644
--- a/src/gen/visit_mut.rs
+++ b/src/gen/visit_mut.rs
@@ -1374,6 +1374,9 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
+ if let Some(ref mut it) = _i.asyncness {
+ tokens_helper(_visitor, &mut it.span)
+ };
if let Some(ref mut it) = _i.movability {
tokens_helper(_visitor, &mut it.span)
};
diff --git a/tests/test_async_fn.rs b/tests/test_asyncness.rs
similarity index 63%
rename from tests/test_async_fn.rs
rename to tests/test_asyncness.rs
index b01d6b6..de9abfc 100644
--- a/tests/test_async_fn.rs
+++ b/tests/test_asyncness.rs
@@ -12,7 +12,7 @@
extern crate syn;
use proc_macro2::Span;
-use syn::{Block, FnDecl, Ident, ItemFn, ReturnType, Visibility};
+use syn::{Block, Expr, ExprBlock, ExprClosure, FnDecl, Ident, ItemFn, ReturnType, Visibility};
use syn::punctuated::Punctuated;
#[test]
@@ -43,3 +43,28 @@
assert_eq!(expected, syn::parse_str(raw).unwrap());
}
+
+#[test]
+fn test_async_closure() {
+ let raw = "async || {}";
+
+ let expected = Expr::Closure(ExprClosure {
+ attrs: vec![],
+ movability: None,
+ asyncness: Some(Default::default()),
+ capture: None,
+ or1_token: Default::default(),
+ inputs: Punctuated::new(),
+ or2_token:Default::default(),
+ output: ReturnType::Default,
+ body: Box::new(Expr::Block(ExprBlock {
+ attrs: vec![],
+ block: Block {
+ brace_token: Default::default(),
+ stmts: vec![],
+ }
+ })),
+ });
+
+ assert_eq!(expected, syn::parse_str(raw).unwrap());
+}