Skip to content

Commit

Permalink
Merge pull request #244 from dtolnay/verbatimfn
Browse files Browse the repository at this point in the history
Handle async impl fn without body
  • Loading branch information
dtolnay authored Mar 24, 2023
2 parents f8a8650 + 344a4f2 commit 346f050
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ proc-macro = true
[dependencies]
proc-macro2 = "1.0"
quote = "1.0"
syn = { version = "2.0", features = ["full", "visit-mut"] }
syn = { version = "2.0.9", features = ["full", "visit-mut"] }

[dev-dependencies]
futures = "0.3"
Expand Down
27 changes: 17 additions & 10 deletions src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::bound::{has_bound, InferredBound, Supertraits};
use crate::lifetime::{AddLifetimeToImplTrait, CollectLifetimes};
use crate::parse::Item;
use crate::receiver::{has_self_in_block, has_self_in_sig, mut_pat, ReplaceSelf};
use crate::verbatim::VerbatimFn;
use proc_macro2::{Span, TokenStream};
use quote::{format_ident, quote, quote_spanned, ToTokens};
use std::collections::BTreeSet as Set;
Expand All @@ -11,7 +12,7 @@ use syn::visit_mut::{self, VisitMut};
use syn::{
parse_quote, parse_quote_spanned, Attribute, Block, FnArg, GenericArgument, GenericParam,
Generics, Ident, ImplItem, Lifetime, LifetimeParam, Pat, PatIdent, PathArguments, Receiver,
ReturnType, Signature, Stmt, Token, TraitItem, Type, TypePath, WhereClause,
ReturnType, Signature, Token, TraitItem, Type, TypePath, WhereClause,
};

impl ToTokens for Item {
Expand Down Expand Up @@ -94,15 +95,27 @@ pub fn expand(input: &mut Item, is_local: bool) {
associated_type_impl_traits: &associated_type_impl_traits,
};
for inner in &mut input.items {
if let ImplItem::Fn(method) = inner {
let sig = &mut method.sig;
if sig.asyncness.is_some() {
match inner {
ImplItem::Fn(method) if method.sig.asyncness.is_some() => {
let sig = &mut method.sig;
let block = &mut method.block;
let has_self = has_self_in_sig(sig) || has_self_in_block(block);
transform_block(context, sig, block);
transform_sig(context, sig, has_self, false, is_local);
method.attrs.push(lint_suppress_with_body());
}
ImplItem::Verbatim(tokens) => {
let mut method = match syn::parse2::<VerbatimFn>(tokens.clone()) {
Ok(method) if method.sig.asyncness.is_some() => method,
_ => continue,
};
let sig = &mut method.sig;
let has_self = has_self_in_sig(sig);
transform_sig(context, sig, has_self, false, is_local);
method.attrs.push(lint_suppress_with_body());
*tokens = quote!(#method);
}
_ => {}
}
}
}
Expand Down Expand Up @@ -329,12 +342,6 @@ fn transform_sig(
// ___ret
// })
fn transform_block(context: Context, sig: &mut Signature, block: &mut Block) {
if let Some(Stmt::Item(syn::Item::Verbatim(item))) = block.stmts.first() {
if block.stmts.len() == 1 && item.to_string() == ";" {
return;
}
}

let mut self_span = None;
let decls = sig
.inputs
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ mod expand;
mod lifetime;
mod parse;
mod receiver;
mod verbatim;

use crate::args::Args;
use crate::expand::expand;
Expand Down
34 changes: 34 additions & 0 deletions src/verbatim.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use proc_macro2::TokenStream;
use quote::{ToTokens, TokenStreamExt};
use syn::parse::{Parse, ParseStream, Result};
use syn::{Attribute, Signature, Token, Visibility};

pub struct VerbatimFn {
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub defaultness: Option<Token![default]>,
pub sig: Signature,
pub semi_token: Token![;],
}

impl Parse for VerbatimFn {
fn parse(input: ParseStream) -> Result<Self> {
Ok(VerbatimFn {
attrs: input.call(Attribute::parse_outer)?,
vis: input.parse()?,
defaultness: input.parse()?,
sig: input.parse()?,
semi_token: input.parse()?,
})
}
}

impl ToTokens for VerbatimFn {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(&self.attrs);
self.vis.to_tokens(tokens);
self.defaultness.to_tokens(tokens);
self.sig.to_tokens(tokens);
self.semi_token.to_tokens(tokens);
}
}

0 comments on commit 346f050

Please sign in to comment.