Skip to content

Commit bd4e0c8

Browse files
committed
Merge pull request 10 from cavedweller/master
2 parents bfe44b3 + dbca3e1 commit bd4e0c8

File tree

3 files changed

+88
-5
lines changed

3 files changed

+88
-5
lines changed

src/expand.rs

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ enum Context<'a> {
3737

3838
type Supertraits = Punctuated<TypeParamBound, Token![+]>;
3939

40-
pub fn expand(input: &mut Item) {
40+
pub fn expand(input: &mut Item, is_local: bool) {
4141
match input {
4242
Item::Trait(input) => {
4343
let context = Context::Trait {
@@ -47,16 +47,32 @@ pub fn expand(input: &mut Item) {
4747
};
4848
for inner in &mut input.items {
4949
if let TraitItem::Method(method) = inner {
50+
<<<<<<< HEAD
5051
let sig = &mut method.sig;
5152
if sig.asyncness.is_some() {
5253
let block = &mut method.default;
5354
let mut has_self = has_self_in_sig(sig);
5455
if let Some(block) = block {
5556
has_self |= has_self_in_block(block);
5657
transform_block(context, sig, block, has_self);
58+
||||||| merged common ancestors
59+
if method.sig.asyncness.is_some() {
60+
if let Some(block) = &mut method.default {
61+
transform_block(context, &method.sig, block);
62+
=======
63+
if method.sig.asyncness.is_some() {
64+
if let Some(block) = &mut method.default {
65+
transform_block(context, &method.sig, block, is_local);
66+
>>>>>>> pr/10
5767
}
5868
let has_default = method.default.is_some();
69+
<<<<<<< HEAD
5970
transform_sig(context, sig, has_self, has_default);
71+
||||||| merged common ancestors
72+
transform_sig(context, &mut method.sig, has_default);
73+
=======
74+
transform_sig(context, &mut method.sig, has_default, is_local);
75+
>>>>>>> pr/10
6076
}
6177
}
6278
}
@@ -69,12 +85,22 @@ pub fn expand(input: &mut Item) {
6985
};
7086
for inner in &mut input.items {
7187
if let ImplItem::Method(method) = inner {
88+
<<<<<<< HEAD
7289
let sig = &mut method.sig;
7390
if sig.asyncness.is_some() {
7491
let block = &mut method.block;
7592
let has_self = has_self_in_sig(sig) || has_self_in_block(block);
7693
transform_block(context, sig, block, has_self);
7794
transform_sig(context, sig, has_self, false);
95+
||||||| merged common ancestors
96+
if method.sig.asyncness.is_some() {
97+
transform_block(context, &method.sig, &mut method.block);
98+
transform_sig(context, &mut method.sig, false);
99+
=======
100+
if method.sig.asyncness.is_some() {
101+
transform_block(context, &method.sig, &mut method.block, is_local);
102+
transform_sig(context, &mut method.sig, false, is_local);
103+
>>>>>>> pr/10
78104
}
79105
}
80106
}
@@ -95,7 +121,13 @@ pub fn expand(input: &mut Item) {
95121
// 'life1: 'async_trait,
96122
// T: 'async_trait,
97123
// Self: Sync + 'async_trait;
124+
<<<<<<< HEAD
98125
fn transform_sig(context: Context, sig: &mut MethodSig, has_self: bool, has_default: bool) {
126+
||||||| merged common ancestors
127+
fn transform_sig(context: Context, sig: &mut MethodSig, has_default: bool) {
128+
=======
129+
fn transform_sig(context: Context, sig: &mut MethodSig, has_default: bool, is_local: bool) {
130+
>>>>>>> pr/10
99131
sig.decl.fn_token.span = sig.asyncness.take().unwrap().span;
100132

101133
let ret = match &sig.decl.output {
@@ -189,9 +221,15 @@ fn transform_sig(context: Context, sig: &mut MethodSig, has_self: bool, has_defa
189221
}
190222
}
191223

224+
let bounds: Supertraits = if is_local {
225+
parse_quote!(#lifetime)
226+
} else {
227+
parse_quote!(#lifetime + core::marker::Send)
228+
};
229+
192230
sig.decl.output = parse_quote! {
193231
-> core::pin::Pin<Box<
194-
dyn core::future::Future<Output = #ret> + core::marker::Send + #lifetime
232+
dyn core::future::Future<Output = #ret> + #bounds
195233
>>
196234
};
197235
}
@@ -206,7 +244,13 @@ fn transform_sig(context: Context, sig: &mut MethodSig, has_self: bool, has_defa
206244
// _self + x
207245
// }
208246
// Pin::from(Box::new(async_trait_method::<T, Self>(self, x)))
247+
<<<<<<< HEAD
209248
fn transform_block(context: Context, sig: &mut MethodSig, block: &mut Block, has_self: bool) {
249+
||||||| merged common ancestors
250+
fn transform_block(context: Context, sig: &MethodSig, block: &mut Block) {
251+
=======
252+
fn transform_block(context: Context, sig: &MethodSig, block: &mut Block, is_local: bool) {
253+
>>>>>>> pr/10
210254
let inner = Ident::new(&format!("__{}", sig.ident), sig.ident.span());
211255
let args = sig
212256
.decl
@@ -275,6 +319,26 @@ fn transform_block(context: Context, sig: &mut MethodSig, block: &mut Block, has
275319
*arg = parse_quote! {
276320
#under_self: &#lifetime #mutability AsyncTrait
277321
};
322+
<<<<<<< HEAD
323+
||||||| merged common ancestors
324+
let (_, generics, _) = generics.split_for_impl();
325+
standalone.decl.generics.params.push(parse_quote! {
326+
AsyncTrait: ?Sized + #name #generics + core::marker::#bound
327+
});
328+
types.push(Ident::new("Self", Span::call_site()));
329+
=======
330+
let (_, generics, _) = generics.split_for_impl();
331+
if is_local {
332+
standalone.decl.generics.params.push(parse_quote! {
333+
AsyncTrait: ?Sized + #name #generics
334+
});
335+
} else {
336+
standalone.decl.generics.params.push(parse_quote! {
337+
AsyncTrait: ?Sized + #name #generics + core::marker::#bound
338+
});
339+
}
340+
types.push(Ident::new("Self", Span::call_site()));
341+
>>>>>>> pr/10
278342
}
279343
Context::Impl { receiver, .. } => {
280344
*arg = parse_quote! {

src/lib.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -305,15 +305,19 @@ mod parse;
305305
mod receiver;
306306

307307
use crate::expand::expand;
308-
use crate::parse::{Item, Nothing};
308+
use crate::parse::Item;
309309
use proc_macro::TokenStream;
310310
use quote::quote;
311311
use syn::parse_macro_input;
312312

313+
mod kw {
314+
syn::custom_keyword!(local);
315+
}
316+
313317
#[proc_macro_attribute]
314318
pub fn async_trait(args: TokenStream, input: TokenStream) -> TokenStream {
315-
parse_macro_input!(args as Nothing);
319+
let local = parse_macro_input!(args as Option<kw::local>).is_some();
316320
let mut item = parse_macro_input!(input as Item);
317-
expand(&mut item);
321+
expand(&mut item, local);
318322
TokenStream::from(quote!(#item))
319323
}

tests/test.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,21 @@ pub async fn test_object_safe_with_default() {
116116
object.f().await;
117117
}
118118

119+
pub async fn test_object_no_send() {
120+
#[async_trait(local)]
121+
trait ObjectSafe: Sync {
122+
async fn f(&self) {}
123+
}
124+
125+
#[async_trait(local)]
126+
impl ObjectSafe for Struct {
127+
async fn f(&self) {}
128+
}
129+
130+
let object = &Struct as &dyn ObjectSafe;
131+
object.f().await;
132+
}
133+
119134
// https://github.com/dtolnay/async-trait/issues/1
120135
mod issue1 {
121136
use async_trait::async_trait;

0 commit comments

Comments
 (0)