Skip to content

Commit 5fb6904

Browse files
committed
Explicitly move all arguments into the async block
1 parent f719ebe commit 5fb6904

File tree

3 files changed

+30
-15
lines changed

3 files changed

+30
-15
lines changed

trait-variant/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ proc-macro = true
2525
[dependencies]
2626
proc-macro2 = "1.0"
2727
quote = "1.0"
28-
syn = { version = "2.0", features = ["full"] }
28+
syn = { version = "2.0", features = ["full", "visit-mut"] }
2929

3030
[dev-dependencies]
3131
tokio = { version = "1", features = ["rt"] }

trait-variant/examples/variant.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ pub trait LocalIntFactory {
2121
fn stream(&self) -> impl Iterator<Item = i32>;
2222
fn call(&self) -> u32;
2323
fn another_async(&self, input: Result<(), &str>) -> Self::MyFut<'_>;
24-
async fn defaulted(&self) -> i32 {
25-
self.make(10, "10").await
24+
async fn defaulted(&self, x: u32) -> i32 {
25+
self.make(x, "10").await
2626
}
2727
async fn defaulted_mut(&mut self) -> i32 {
2828
self.make(10, "10").await

trait-variant/src/variant.rs

+27-12
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,8 @@ use std::iter;
1111
use proc_macro2::{Span, TokenStream};
1212
use quote::quote;
1313
use syn::{
14-
parse::{Parse, ParseStream},
15-
parse_macro_input,
16-
punctuated::Punctuated,
17-
token::Plus,
18-
Error, FnArg, GenericParam, Ident, ItemTrait, Pat, PatType, Receiver, Result, ReturnType,
19-
Signature, Token, TraitBound, TraitItem, TraitItemConst, TraitItemFn, TraitItemType, Type,
20-
TypeGenerics, TypeImplTrait, TypeParam, TypeParamBound, WhereClause,
14+
parse::{Parse, ParseStream}, parse_macro_input, parse_quote, punctuated::Punctuated, token::Plus, Error, FnArg, GenericParam, Ident, ItemTrait, Pat, PatIdent, PatType, Receiver, Result, ReturnType, Signature, Token, TraitBound, TraitItem, TraitItemConst, TraitItemFn, TraitItemType, Type, TypeGenerics, TypeImplTrait, TypeParam, TypeParamBound, TypeReference, WhereClause
2115
};
22-
use syn::{parse_quote, TypeReference};
2316

2417
struct Attrs {
2518
variant: MakeVariant,
@@ -154,10 +147,32 @@ fn transform_item(item: &TraitItem, bounds: &Vec<TypeParamBound>) -> TraitItem {
154147
output: ReturnType::Type(syn::parse2(quote! { -> }).unwrap(), Box::new(ty)),
155148
..sig.clone()
156149
},
157-
fn_item
158-
.default
159-
.as_ref()
160-
.map(|b| syn::parse2(quote! { { async move #b } }).unwrap()),
150+
fn_item.default.as_ref().map(|b| {
151+
let items = sig.inputs.iter().map(|i| match i {
152+
FnArg::Receiver(Receiver { self_token, .. }) => {
153+
quote! { let __self = #self_token; }
154+
}
155+
FnArg::Typed(PatType { pat, .. }) => match pat.as_ref() {
156+
Pat::Ident(PatIdent { ident, .. }) => quote! { let #ident = #ident; },
157+
_ => todo!(),
158+
},
159+
});
160+
161+
struct ReplaceSelfVisitor;
162+
impl syn::visit_mut::VisitMut for ReplaceSelfVisitor {
163+
fn visit_ident_mut(&mut self, ident: &mut syn::Ident) {
164+
if ident == "self" {
165+
*ident = syn::Ident::new("__self", ident.span());
166+
}
167+
syn::visit_mut::visit_ident_mut(self, ident);
168+
}
169+
}
170+
171+
let mut block = b.clone();
172+
syn::visit_mut::visit_block_mut(&mut ReplaceSelfVisitor, &mut block);
173+
174+
parse_quote! { { async move { #(#items)* #block} } }
175+
}),
161176
)
162177
} else {
163178
match &sig.output {

0 commit comments

Comments
 (0)