Skip to content

Commit 346f050

Browse files
authored
Merge pull request #244 from dtolnay/verbatimfn
Handle async impl fn without body
2 parents f8a8650 + 344a4f2 commit 346f050

File tree

4 files changed

+53
-11
lines changed

4 files changed

+53
-11
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ proc-macro = true
1717
[dependencies]
1818
proc-macro2 = "1.0"
1919
quote = "1.0"
20-
syn = { version = "2.0", features = ["full", "visit-mut"] }
20+
syn = { version = "2.0.9", features = ["full", "visit-mut"] }
2121

2222
[dev-dependencies]
2323
futures = "0.3"

src/expand.rs

+17-10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::bound::{has_bound, InferredBound, Supertraits};
22
use crate::lifetime::{AddLifetimeToImplTrait, CollectLifetimes};
33
use crate::parse::Item;
44
use crate::receiver::{has_self_in_block, has_self_in_sig, mut_pat, ReplaceSelf};
5+
use crate::verbatim::VerbatimFn;
56
use proc_macro2::{Span, TokenStream};
67
use quote::{format_ident, quote, quote_spanned, ToTokens};
78
use std::collections::BTreeSet as Set;
@@ -11,7 +12,7 @@ use syn::visit_mut::{self, VisitMut};
1112
use syn::{
1213
parse_quote, parse_quote_spanned, Attribute, Block, FnArg, GenericArgument, GenericParam,
1314
Generics, Ident, ImplItem, Lifetime, LifetimeParam, Pat, PatIdent, PathArguments, Receiver,
14-
ReturnType, Signature, Stmt, Token, TraitItem, Type, TypePath, WhereClause,
15+
ReturnType, Signature, Token, TraitItem, Type, TypePath, WhereClause,
1516
};
1617

1718
impl ToTokens for Item {
@@ -94,15 +95,27 @@ pub fn expand(input: &mut Item, is_local: bool) {
9495
associated_type_impl_traits: &associated_type_impl_traits,
9596
};
9697
for inner in &mut input.items {
97-
if let ImplItem::Fn(method) = inner {
98-
let sig = &mut method.sig;
99-
if sig.asyncness.is_some() {
98+
match inner {
99+
ImplItem::Fn(method) if method.sig.asyncness.is_some() => {
100+
let sig = &mut method.sig;
100101
let block = &mut method.block;
101102
let has_self = has_self_in_sig(sig) || has_self_in_block(block);
102103
transform_block(context, sig, block);
103104
transform_sig(context, sig, has_self, false, is_local);
104105
method.attrs.push(lint_suppress_with_body());
105106
}
107+
ImplItem::Verbatim(tokens) => {
108+
let mut method = match syn::parse2::<VerbatimFn>(tokens.clone()) {
109+
Ok(method) if method.sig.asyncness.is_some() => method,
110+
_ => continue,
111+
};
112+
let sig = &mut method.sig;
113+
let has_self = has_self_in_sig(sig);
114+
transform_sig(context, sig, has_self, false, is_local);
115+
method.attrs.push(lint_suppress_with_body());
116+
*tokens = quote!(#method);
117+
}
118+
_ => {}
106119
}
107120
}
108121
}
@@ -329,12 +342,6 @@ fn transform_sig(
329342
// ___ret
330343
// })
331344
fn transform_block(context: Context, sig: &mut Signature, block: &mut Block) {
332-
if let Some(Stmt::Item(syn::Item::Verbatim(item))) = block.stmts.first() {
333-
if block.stmts.len() == 1 && item.to_string() == ";" {
334-
return;
335-
}
336-
}
337-
338345
let mut self_span = None;
339346
let decls = sig
340347
.inputs

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ mod expand;
325325
mod lifetime;
326326
mod parse;
327327
mod receiver;
328+
mod verbatim;
328329

329330
use crate::args::Args;
330331
use crate::expand::expand;

src/verbatim.rs

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use proc_macro2::TokenStream;
2+
use quote::{ToTokens, TokenStreamExt};
3+
use syn::parse::{Parse, ParseStream, Result};
4+
use syn::{Attribute, Signature, Token, Visibility};
5+
6+
pub struct VerbatimFn {
7+
pub attrs: Vec<Attribute>,
8+
pub vis: Visibility,
9+
pub defaultness: Option<Token![default]>,
10+
pub sig: Signature,
11+
pub semi_token: Token![;],
12+
}
13+
14+
impl Parse for VerbatimFn {
15+
fn parse(input: ParseStream) -> Result<Self> {
16+
Ok(VerbatimFn {
17+
attrs: input.call(Attribute::parse_outer)?,
18+
vis: input.parse()?,
19+
defaultness: input.parse()?,
20+
sig: input.parse()?,
21+
semi_token: input.parse()?,
22+
})
23+
}
24+
}
25+
26+
impl ToTokens for VerbatimFn {
27+
fn to_tokens(&self, tokens: &mut TokenStream) {
28+
tokens.append_all(&self.attrs);
29+
self.vis.to_tokens(tokens);
30+
self.defaultness.to_tokens(tokens);
31+
self.sig.to_tokens(tokens);
32+
self.semi_token.to_tokens(tokens);
33+
}
34+
}

0 commit comments

Comments
 (0)