Skip to content

Commit

Permalink
Update proc-macro2, syn and quote dependencies to 1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Aug 3, 2019
1 parent 20a2d67 commit 0ffa46b
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 53 deletions.
6 changes: 3 additions & 3 deletions futures-async-stream-macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ proc-macro = true
[features]

[dependencies]
proc-macro2 = "0.4.13"
quote = "0.6.8"
syn = { version = "0.15.41", features = ["full", "fold"] }
proc-macro2-next = "1.0.0-rc1"
quote-next = "1.0.0-rc1" # https://github.com/dtolnay/quote/issues/124
syn-next = { version = "1.0.0-rc1", features = ["full", "fold"] } # https://github.com/dtolnay/syn/issues/687
13 changes: 7 additions & 6 deletions futures-async-stream-macro/src/elision.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use proc_macro2::Span;
use syn::{
fold::Fold, punctuated::Punctuated, token::Comma, ArgSelfRef, FnArg, GenericParam, Lifetime,
LifetimeDef, TypeReference,
fold::Fold, punctuated::Punctuated, token::Comma, FnArg, GenericParam, Lifetime, LifetimeDef,
Receiver, TypeReference,
};

pub(super) fn unelide_lifetimes(
Expand Down Expand Up @@ -49,10 +49,11 @@ impl<'a> UnelideLifetimes<'a> {

impl Fold for UnelideLifetimes<'_> {
// Handling self arguments
fn fold_arg_self_ref(&mut self, arg: ArgSelfRef) -> ArgSelfRef {
let ArgSelfRef { and_token, lifetime, mutability, self_token } = arg;
let lifetime = Some(self.expand_lifetime(lifetime));
ArgSelfRef { and_token, lifetime, mutability, self_token }
fn fold_receiver(&mut self, receiver: Receiver) -> Receiver {
let Receiver { attrs, reference, mutability, self_token } = receiver;
let reference = reference
.map(|(and_token, lifetime)| (and_token, Some(self.expand_lifetime(lifetime))));
Receiver { attrs, reference, mutability, self_token }
}

// If the lifetime is `'_`, replace it with a new unelided lifetime
Expand Down
54 changes: 29 additions & 25 deletions futures-async-stream-macro/src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use quote::{quote, ToTokens};
use syn::{
fold::Fold,
parse::{Parse, ParseStream},
token, ArgCaptured, Expr, FnArg, FnDecl, Ident, ItemFn, Pat, PatIdent, Result, ReturnType,
token, Expr, FnArg, Ident, ItemFn, Pat, PatIdent, PatType, Result, ReturnType, Signature,
Token, Type, TypeTuple,
};

Expand Down Expand Up @@ -38,18 +38,18 @@ fn parse_async_stream_fn(args: TokenStream, input: TokenStream) -> Result<TokenS
let args: Arg = syn::parse2(args)?;
let item: ItemFn = syn::parse2(input)?;

if let Some(constness) = item.constness {
if let Some(constness) = item.sig.constness {
return Err(error!(constness, "async stream may not be const"));
}
if let Some(variadic) = item.decl.variadic {
if let Some(variadic) = item.sig.variadic {
return Err(error!(variadic, "async stream may not be variadic"));
}

if item.asyncness.is_none() {
return Err(error!(item.decl.fn_token, "async stream must be declared as async"));
if item.sig.asyncness.is_none() {
return Err(error!(item.sig.fn_token, "async stream must be declared as async"));
}

if let ReturnType::Type(_, ty) = &item.decl.output {
if let ReturnType::Type(_, ty) = &item.sig.output {
match &**ty {
Type::Tuple(TypeTuple { elems, .. }) if elems.is_empty() => {}
_ => return Err(error!(ty, "async stream must return the unit type")),
Expand All @@ -60,8 +60,8 @@ fn parse_async_stream_fn(args: TokenStream, input: TokenStream) -> Result<TokenS
}

fn expand_async_stream_fn(item: ItemFn, item_ty: &Type) -> TokenStream {
let ItemFn { ident, vis, unsafety, abi, block, decl, attrs, .. } = item;
let FnDecl { inputs, mut generics, fn_token, .. } = *decl;
let ItemFn { attrs, vis, sig, block, .. } = item;
let Signature { unsafety, abi, fn_token, ident, mut generics, inputs, .. } = sig;
let where_clause = &generics.where_clause;

// Desugar `async fn`
Expand All @@ -87,29 +87,33 @@ fn expand_async_stream_fn(item: ItemFn, item_ty: &Type) -> TokenStream {
let mut patterns = Vec::new();
let mut temp_bindings = Vec::new();
for (i, input) in inputs.into_iter().enumerate() {
match input {
FnArg::Captured(ArgCaptured { pat: Pat::Ident(ref pat), .. })
if pat.ident == "self" =>
{
if let FnArg::Typed(PatType { attrs, pat, ty, colon_token }) = input {
let captured_naturally = match &*pat {
// `self: Box<Self>` will get captured naturally
inputs_no_patterns.push(input);
}
FnArg::Captured(ArgCaptured {
pat: pat @ Pat::Ident(PatIdent { by_ref: Some(_), .. }),
ty,
colon_token,
}) => {
Pat::Ident(pat) if pat.ident == "self" => true,
Pat::Ident(PatIdent { by_ref: Some(_), .. }) => false,
// Other arguments get captured naturally
_ => true,
};
if captured_naturally {
inputs_no_patterns.push(FnArg::Typed(PatType { attrs, pat, ty, colon_token }));
continue;
} else {
// `ref a: B` (or some similar pattern)
patterns.push(pat);
let ident = Ident::new(&format!("__arg_{}", i), Span::call_site());
temp_bindings.push(ident.clone());
let pat = PatIdent { by_ref: None, mutability: None, ident, subpat: None }.into();
inputs_no_patterns.push(ArgCaptured { pat, ty, colon_token }.into());
}
_ => {
// Other arguments get captured naturally
inputs_no_patterns.push(input);
let pat = Box::new(Pat::Ident(PatIdent {
attrs: Vec::new(),
by_ref: None,
mutability: None,
ident,
subpat: None,
}));
inputs_no_patterns.push(PatType { attrs, pat, ty, colon_token }.into());
}
} else {
inputs_no_patterns.push(input);
}
}

Expand Down
32 changes: 13 additions & 19 deletions futures-async-stream-macro/src/visitor.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use quote::{quote, ToTokens};
use quote::{quote, quote_spanned, ToTokens};
use syn::{
fold::{self, Fold},
Expr, ExprCall, ExprField, ExprForLoop, ExprMacro, ExprYield, Item, Member,
spanned::Spanned,
Expr, ExprAwait, ExprCall, ExprForLoop, ExprMacro, ExprYield, Item,
};

use crate::{async_stream_block, utils::expr_compile_error};
Expand Down Expand Up @@ -50,7 +51,7 @@ impl Visitor {
if !(expr.attrs.len() == 1 && expr.attrs[0].path.is_ident("for_await")) {
return Expr::ForLoop(expr);
}
if !expr.attrs[0].tts.is_empty() {
if !expr.attrs[0].tokens.is_empty() {
return expr_compile_error(&error!(
expr.attrs.pop(),
"attribute must be of the form `#[for_await]`"
Expand Down Expand Up @@ -128,32 +129,28 @@ impl Visitor {
/// Expands `async_stream_block!` macro.
fn expand_macro(&mut self, mut expr: ExprMacro) -> Expr {
if expr.mac.path.is_ident("async_stream_block") {
let mut e: ExprCall = syn::parse(async_stream_block(expr.mac.tts.into())).unwrap();
let mut e: ExprCall = syn::parse(async_stream_block(expr.mac.tokens.into())).unwrap();
e.attrs.append(&mut expr.attrs);
Expr::Call(e)
} else {
Expr::Macro(expr)
}
}

/// Expands `<expr>.await` in `async_stream` scope.
/// Expands `<base>.await` in `async_stream` scope.
///
/// It needs to adjust the type yielded by the macro because generators used internally by
/// async fn yield `()` type, but generators used internally by `async_stream` yield
/// `Poll<U>` type.
fn expand_await(&mut self, expr: ExprField) -> Expr {
fn expand_await(&mut self, expr: ExprAwait) -> Expr {
if self.scope != Stream {
return Expr::Field(expr);
return Expr::Await(expr);
}

match &expr.member {
Member::Named(x) if x == "await" => {}
_ => return Expr::Field(expr),
}
let expr = expr.base;
let ExprAwait { base, await_token, .. } = expr;

syn::parse2(quote! {{
let mut __pinned = #expr;
syn::parse2(quote_spanned! { await_token.span() => {
let mut __pinned = #base;
loop {
if let ::futures_async_stream::core_reexport::task::Poll::Ready(x) =
::futures_async_stream::stream::poll_with_tls_context(unsafe {
Expand All @@ -166,10 +163,7 @@ impl Visitor {
yield ::futures_async_stream::core_reexport::task::Poll::Pending
}
}})
// As macro input (<expr>) is untrusted, use `syn::parse2` + `expr_compile_error`
// instead of `syn::parse_quote!` to generate better error messages (`syn::parse_quote!`
// panics if fail to parse).
.unwrap_or_else(|e| expr_compile_error(&e))
.unwrap()
}
}

Expand All @@ -190,7 +184,7 @@ impl Fold for Visitor {

let expr = match fold::fold_expr(self, expr) {
Expr::Yield(expr) => Expr::Yield(self.expand_yield(expr)),
Expr::Field(expr) => self.expand_await(expr),
Expr::Await(expr) => self.expand_await(expr),
Expr::ForLoop(expr) => self.expand_for_loop(expr),
Expr::Macro(expr) => self.expand_macro(expr),
expr => expr,
Expand Down

0 comments on commit 0ffa46b

Please sign in to comment.