diff --git a/Cargo.toml b/Cargo.toml index 622f0b6..56b74ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "entrait" -version = "0.6.0" +version = "0.7.0-dev" authors = ["Audun Halland "] edition = "2021" -rust-version = "1.60" +rust-version = "1.75" license = "MIT" description = "Loosely coupled Rust application design made easy" repository = "https://github.com/audunhalland/entrait/" @@ -19,16 +19,17 @@ boxed-futures = ["dep:async-trait"] nightly-tests = [] [dependencies] -entrait_macros = { path = "entrait_macros", version = "0.6.0" } +entrait_macros = { path = "entrait_macros", version = "0.7.0-dev" } implementation = "0.1" async-trait = { version = "0.1", optional = true } -unimock = { version = "0.6", optional = true } +unimock = { version = "0.6.1", optional = true } [dev-dependencies] tokio = { version = "1", features = ["macros", "rt"] } feignhttp = "0.5" mockall = "0.11" tracing = "0.1" +async-trait = "0.1" [lib] # do not run doctest by default with `cargo hack`. They are tested with a separate `cargo test --doc` run. diff --git a/entrait_macros/Cargo.toml b/entrait_macros/Cargo.toml index 17b8b90..86d1df6 100644 --- a/entrait_macros/Cargo.toml +++ b/entrait_macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "entrait_macros" -version = "0.6.0" +version = "0.7.0-dev" authors = ["Audun Halland "] edition = "2021" rust-version = "1.60" diff --git a/entrait_macros/src/attributes.rs b/entrait_macros/src/attributes.rs index 3a9f40e..0949073 100644 --- a/entrait_macros/src/attributes.rs +++ b/entrait_macros/src/attributes.rs @@ -2,7 +2,7 @@ use crate::analyze_generics::TraitFn; use crate::generics::{self, TraitIndirection}; use crate::idents::CrateIdents; use crate::input::FnInputMode; -use crate::opt::{AsyncStrategy, MockApiIdent, Opts, SpanOpt}; +use crate::opt::{MockApiIdent, Opts}; use crate::token_util::{comma_sep, push_tokens}; use proc_macro2::{Span, TokenStream}; @@ -229,58 +229,22 @@ impl ToTokens for MockallAutomockParams { } } -pub fn opt_async_trait_attr<'s, 'o>( - opts: &'s Opts, - crate_idents: &'s CrateIdents, - trait_fns: impl Iterator, -) -> Option { - match ( - opts.async_strategy(), - generics::has_any_async(trait_fns.map(|trait_fn| trait_fn.sig())), - ) { - (SpanOpt(AsyncStrategy::BoxFuture, span), true) => Some(Attr(AsyncTraitParams { - crate_idents, - use_static: false, - span, - })), - (SpanOpt(AsyncStrategy::AssociatedFuture, span), true) => Some(Attr(AsyncTraitParams { - crate_idents, - use_static: true, - span, - })), - _ => None, - } -} - pub struct AsyncTraitParams<'a> { pub crate_idents: &'a CrateIdents, - pub use_static: bool, pub span: Span, } impl<'a> ToTokens for AsyncTraitParams<'a> { fn to_tokens(&self, stream: &mut TokenStream) { let span = self.span; - if self.use_static { - push_tokens!( - stream, - syn::token::PathSep(span), - self.crate_idents.entrait, - syn::token::PathSep(span), - syn::Ident::new("static_async", span), - syn::token::PathSep(span), - syn::Ident::new("async_trait", span) - ); - } else { - push_tokens!( - stream, - syn::token::PathSep(span), - self.crate_idents.entrait, - syn::token::PathSep(span), - syn::Ident::new("__async_trait", span), - syn::token::PathSep(span), - syn::Ident::new("async_trait", span) - ); - } + push_tokens!( + stream, + syn::token::PathSep(span), + self.crate_idents.entrait, + syn::token::PathSep(span), + syn::Ident::new("__async_trait", span), + syn::token::PathSep(span), + syn::Ident::new("async_trait", span) + ); } } diff --git a/entrait_macros/src/entrait_fn/input_attr.rs b/entrait_macros/src/entrait_fn/input_attr.rs index bfc502f..39931c0 100644 --- a/entrait_macros/src/entrait_fn/input_attr.rs +++ b/entrait_macros/src/entrait_fn/input_attr.rs @@ -36,9 +36,6 @@ impl Parse for EntraitFnAttr { EntraitOpt::BoxFuture(opt) => { async_strategy = Some(SpanOpt(AsyncStrategy::BoxFuture, opt.1)) } - EntraitOpt::AssociatedFuture(opt) => { - async_strategy = Some(SpanOpt(AsyncStrategy::AssociatedFuture, opt.1)) - } EntraitOpt::Export(opt) => export = Some(opt), EntraitOpt::MockApi(ident) => mock_api = Some(ident), EntraitOpt::Unimock(opt) => unimock = Some(opt), diff --git a/entrait_macros/src/entrait_fn/mod.rs b/entrait_macros/src/entrait_fn/mod.rs index cb4d0f8..e98ac92 100644 --- a/entrait_macros/src/entrait_fn/mod.rs +++ b/entrait_macros/src/entrait_fn/mod.rs @@ -13,6 +13,7 @@ use crate::generics; use crate::input::FnInputMode; use crate::input::{InputFn, InputMod, ModItem}; use crate::signature; +use crate::sub_attributes::analyze_sub_attributes; use crate::trait_codegen::Supertraits; use crate::trait_codegen::TraitCodegen; use input_attr::*; @@ -33,6 +34,7 @@ pub fn entrait_for_single_fn(attr: &EntraitFnAttr, input_fn: InputFn) -> syn::Re opts: &attr.opts, } .analyze(input_fn.input_sig(), &mut generics_analyzer)?]; + let sub_attributes = analyze_sub_attributes(&input_fn.fn_attrs); let trait_dependency_mode = detect_trait_dependency_mode( &fn_input_mode, @@ -40,15 +42,13 @@ pub fn entrait_for_single_fn(attr: &EntraitFnAttr, input_fn: InputFn) -> syn::Re &attr.crate_idents, attr.trait_ident.span(), )?; - let use_associated_future = - generics::detect_use_associated_future(&attr.opts, [&input_fn].into_iter()); - let trait_generics = generics_analyzer.into_trait_generics(); let trait_def = TraitCodegen { opts: &attr.opts, crate_idents: &attr.crate_idents, trait_indirection: generics::TraitIndirection::Plain, trait_dependency_mode: &trait_dependency_mode, + sub_attributes: &sub_attributes, } .gen_trait_def( &attr.trait_visibility, @@ -58,6 +58,7 @@ pub fn entrait_for_single_fn(attr: &EntraitFnAttr, input_fn: InputFn) -> syn::Re &trait_fns, &fn_input_mode, )?; + let impl_block = fn_delegation_codegen::FnDelegationCodegen { opts: &attr.opts, crate_idents: &attr.crate_idents, @@ -67,7 +68,7 @@ pub fn entrait_for_single_fn(attr: &EntraitFnAttr, input_fn: InputFn) -> syn::Re trait_generics: &trait_generics, fn_input_mode: &fn_input_mode, trait_dependency_mode: &trait_dependency_mode, - use_associated_future, + sub_attributes: &sub_attributes, } .gen_impl_block(&trait_fns); @@ -79,11 +80,15 @@ pub fn entrait_for_single_fn(attr: &EntraitFnAttr, input_fn: InputFn) -> syn::Re .. } = input_fn; - Ok(quote! { + let out = quote! { #(#fn_attrs)* #fn_vis #fn_sig #fn_body #trait_def #impl_block - }) + }; + + // println!("\n\nfn output: {out}"); + + Ok(out) } pub fn entrait_for_mod(attr: &EntraitFnAttr, input_mod: InputMod) -> syn::Result { @@ -103,6 +108,7 @@ pub fn entrait_for_mod(attr: &EntraitFnAttr, input_mod: InputMod) -> syn::Result .analyze(input_fn.input_sig(), &mut generics_analyzer) }) .collect::>>()?; + let sub_attributes = analyze_sub_attributes(&input_mod.attrs); let trait_dependency_mode = detect_trait_dependency_mode( &fn_input_mode, @@ -110,10 +116,6 @@ pub fn entrait_for_mod(attr: &EntraitFnAttr, input_mod: InputMod) -> syn::Result &attr.crate_idents, attr.trait_ident.span(), )?; - let use_associated_future = generics::detect_use_associated_future( - &attr.opts, - input_mod.items.iter().filter_map(ModItem::filter_pub_fn), - ); let trait_generics = generics_analyzer.into_trait_generics(); let trait_def = TraitCodegen { @@ -121,6 +123,7 @@ pub fn entrait_for_mod(attr: &EntraitFnAttr, input_mod: InputMod) -> syn::Result crate_idents: &attr.crate_idents, trait_indirection: generics::TraitIndirection::Plain, trait_dependency_mode: &trait_dependency_mode, + sub_attributes: &sub_attributes, } .gen_trait_def( &attr.trait_visibility, @@ -139,7 +142,7 @@ pub fn entrait_for_mod(attr: &EntraitFnAttr, input_mod: InputMod) -> syn::Result trait_generics: &trait_generics, fn_input_mode: &fn_input_mode, trait_dependency_mode: &trait_dependency_mode, - use_associated_future, + sub_attributes: &sub_attributes, } .gen_impl_block(&trait_fns); diff --git a/entrait_macros/src/entrait_impl/mod.rs b/entrait_macros/src/entrait_impl/mod.rs index c20ddb5..c974340 100644 --- a/entrait_macros/src/entrait_impl/mod.rs +++ b/entrait_macros/src/entrait_impl/mod.rs @@ -10,6 +10,8 @@ use crate::input::InputImpl; use crate::opt::AsyncStrategy; use crate::opt::SpanOpt; use crate::signature; +use crate::sub_attributes::analyze_sub_attributes; +use crate::sub_attributes::SubAttribute; use quote::quote; use syn::spanned::Spanned; @@ -58,16 +60,13 @@ pub fn output_tokens_for_impl( .analyze(input_fn.input_sig(), &mut generics_analyzer) }) .collect::>>()?; + let sub_attributes = analyze_sub_attributes(&attrs); let trait_generics = generics_analyzer.into_trait_generics(); let fn_input_mode = crate::input::FnInputMode::ImplBlock(&self_ty); let trait_dependency_mode = detect_trait_dependency_mode(&fn_input_mode, &trait_fns, &attr.crate_idents, trait_span)?; - let use_associated_future = generics::detect_use_associated_future( - &attr.opts, - items.iter().filter_map(ImplItem::filter_fn), - ); let impl_indirection = match attr.impl_kind { ImplKind::Static => generics::ImplIndirection::Static { ty: &self_ty }, @@ -83,12 +82,16 @@ pub fn output_tokens_for_impl( trait_generics: &trait_generics, fn_input_mode: &fn_input_mode, trait_dependency_mode: &trait_dependency_mode, - use_associated_future, + sub_attributes: &sub_attributes, } .gen_impl_block(&trait_fns); + let inherent_sub_attrs = sub_attributes + .iter() + .filter(|sub_attr| !matches!(sub_attr, SubAttribute::AsyncTrait(_))); + Ok(quote! { - #(#attrs)* + #(#inherent_sub_attrs)* #unsafety #impl_token #self_ty { #(#items)* } diff --git a/entrait_macros/src/entrait_trait/input_attr.rs b/entrait_macros/src/entrait_trait/input_attr.rs index fe7b702..aeca1ea 100644 --- a/entrait_macros/src/entrait_trait/input_attr.rs +++ b/entrait_macros/src/entrait_trait/input_attr.rs @@ -43,9 +43,6 @@ impl Parse for EntraitTraitAttr { EntraitOpt::BoxFuture(opt) => { async_strategy = Some(SpanOpt(AsyncStrategy::BoxFuture, opt.1)) } - EntraitOpt::AssociatedFuture(opt) => { - async_strategy = Some(SpanOpt(AsyncStrategy::AssociatedFuture, opt.1)) - } EntraitOpt::MockApi(ident) => mock_api = Some(ident), EntraitOpt::Unimock(opt) => unimock = Some(opt), EntraitOpt::Mockall(opt) => mockall = Some(opt), diff --git a/entrait_macros/src/entrait_trait/mod.rs b/entrait_macros/src/entrait_trait/mod.rs index d8beecf..5ea9ed4 100644 --- a/entrait_macros/src/entrait_trait/mod.rs +++ b/entrait_macros/src/entrait_trait/mod.rs @@ -7,7 +7,6 @@ use input_attr::EntraitTraitAttr; use proc_macro2::Span; use crate::analyze_generics::TraitFn; -use crate::attributes; use crate::entrait_trait::input_attr::ImplTrait; use crate::generics; use crate::generics::TraitDependencyMode; @@ -15,6 +14,8 @@ use crate::idents::GenericIdents; use crate::input::FnInputMode; use crate::input::LiteralAttrs; use crate::opt::*; +use crate::sub_attributes::analyze_sub_attributes; +use crate::sub_attributes::SubAttribute; use crate::token_util::*; use crate::trait_codegen::Supertraits; use crate::trait_codegen::TraitCodegen; @@ -46,19 +47,15 @@ pub fn output_tokens( syn::TraitItem::Fn(method) => method.sig.asyncness.is_some(), _ => false, })); - let impl_attrs = item_trait - .attrs - .iter() - .filter(|attr| { - matches!( - attr.path().segments.last(), - Some(last_segment) if last_segment.ident == "async_trait" - ) - }) - .cloned() - .collect::>(); let out_trait = out_trait::analyze_trait(item_trait)?; + let sub_attributes = analyze_sub_attributes(&out_trait.attrs); + let impl_sub_attributes: Vec<_> = sub_attributes + .iter() + .copied() + .filter(|sub_attr| matches!(sub_attr, SubAttribute::AsyncTrait(_))) + .collect(); + let trait_dependency_mode = TraitDependencyMode::Generic(GenericIdents::new( &attr.crate_idents, out_trait.ident.span(), @@ -68,20 +65,20 @@ pub fn output_tokens( _ => panic!(), }; - let mut impl_async_trait_attr = - attributes::opt_async_trait_attr(&attr.opts, &attr.crate_idents, out_trait.fns.iter()); - if !impl_attrs.is_empty() { - impl_async_trait_attr = None; - } - - let delegation_trait_def = - gen_impl_delegation_trait_defs(&out_trait, &trait_dependency_mode, generic_idents, &attr)?; + let delegation_trait_def = gen_impl_delegation_trait_defs( + &out_trait, + &trait_dependency_mode, + generic_idents, + &impl_sub_attributes, + &attr, + )?; let trait_def = TraitCodegen { crate_idents: &attr.crate_idents, opts: &attr.opts, trait_indirection: generics::TraitIndirection::Trait, trait_dependency_mode: &trait_dependency_mode, + sub_attributes: &sub_attributes, } .gen_trait_def( &out_trait.vis, @@ -95,7 +92,6 @@ pub fn output_tokens( let trait_ident = &out_trait.ident; let params = out_trait.generics.impl_params_from_idents( generic_idents, - generics::UseAssociatedFuture(false), generics::TakesSelfByValue(false), // BUG? ); let args = out_trait @@ -111,35 +107,30 @@ pub fn output_tokens( span: trait_ident_span, }; - let impl_assoc_types = out_trait.fns.iter().filter_map(|trait_fn| { - trait_fn - .entrait_sig - .associated_fut_impl(generics::TraitIndirection::Plain, &attr.crate_idents) - }); - let method_items = out_trait .fns .iter() .map(|trait_fn| gen_delegation_method(trait_fn, generic_idents, &attr, contains_async)); - Ok(quote! { + let out = quote! { #trait_def #delegation_trait_def - #(#impl_attrs)* - #impl_async_trait_attr + #(#impl_sub_attributes)* impl #params #trait_ident #args for #self_ty #where_clause { - #(#impl_assoc_types)* #(#method_items)* } - }) + }; + + Ok(out) } fn gen_impl_delegation_trait_defs( out_trait: &OutTrait, trait_dependency_mode: &TraitDependencyMode, generic_idents: &GenericIdents, + impl_sub_attributes: &[SubAttribute], attr: &EntraitTraitAttr, ) -> syn::Result> { let entrait = &generic_idents.crate_idents.entrait; @@ -192,6 +183,7 @@ fn gen_impl_delegation_trait_defs( opts: &no_mock_opts, trait_indirection: generics::TraitIndirection::StaticImpl, trait_dependency_mode, + sub_attributes: impl_sub_attributes, } .gen_trait_def( &trait_copy.vis, @@ -206,6 +198,7 @@ fn gen_impl_delegation_trait_defs( )?; Ok(Some(quote! { + #(#impl_sub_attributes)* #trait_def pub trait #delegation_ident { @@ -245,6 +238,7 @@ fn gen_impl_delegation_trait_defs( opts: &no_mock_opts, trait_indirection: generics::TraitIndirection::DynamicImpl, trait_dependency_mode, + sub_attributes: impl_sub_attributes, } .gen_trait_def( &trait_copy.vis, @@ -258,7 +252,10 @@ fn gen_impl_delegation_trait_defs( &FnInputMode::RawTrait(LiteralAttrs(&[])), )?; - Ok(Some(trait_def)) + Ok(Some(quote! { + #(#impl_sub_attributes)* + #trait_def + })) } _ => Err(syn::Error::new( proc_macro2::Span::call_site(), @@ -291,7 +288,6 @@ fn gen_delegation_method<'s>( DelegatingMethod { attr, trait_fn, - needs_async_move: true, call: quote! { // TODO: pass additional generic arguments(?) <#impl_t::Target as #impl_trait_ident<#impl_t>>::#fn_ident(self, #(#arguments),*) @@ -325,14 +321,12 @@ fn gen_delegation_method<'s>( DelegatingMethod { attr, trait_fn, - needs_async_move: false, call, } } (None, Some(SpanOpt(Delegate::ByRef(RefDelegate::AsRef), _))) => DelegatingMethod { attr, trait_fn, - needs_async_move: false, call: quote! { self.as_ref().as_ref().#fn_ident(#(#arguments),*) }, @@ -340,7 +334,6 @@ fn gen_delegation_method<'s>( (None, Some(SpanOpt(Delegate::ByRef(RefDelegate::Borrow), _))) => DelegatingMethod { attr, trait_fn, - needs_async_move: false, call: quote! { self.as_ref().borrow().#fn_ident(#(#arguments),*) }, @@ -348,7 +341,6 @@ fn gen_delegation_method<'s>( _ => DelegatingMethod { attr, trait_fn, - needs_async_move: false, call: quote! { self.as_ref().#fn_ident(#(#arguments),*) }, @@ -359,7 +351,6 @@ fn gen_delegation_method<'s>( struct DelegatingMethod<'s> { attr: &'s EntraitTraitAttr, trait_fn: &'s TraitFn, - needs_async_move: bool, call: TokenStream, } @@ -400,7 +391,8 @@ impl<'s> ToTokens for DelegatingMethod<'s> { } self.trait_fn.sig().to_tokens(stream); syn::token::Brace::default().surround(stream, |stream| { - if self.needs_async_move && self.trait_fn.entrait_sig.associated_fut.is_some() { + // if self.needs_async_move && self.trait_fn.entrait_sig.associated_fut.is_some() { + if false { push_tokens!( stream, syn::token::Async::default(), diff --git a/entrait_macros/src/fn_delegation_codegen.rs b/entrait_macros/src/fn_delegation_codegen.rs index 491e995..b0ed2aa 100644 --- a/entrait_macros/src/fn_delegation_codegen.rs +++ b/entrait_macros/src/fn_delegation_codegen.rs @@ -5,7 +5,6 @@ use quote::{quote, quote_spanned}; use syn::spanned::Spanned; use crate::analyze_generics::TraitFn; -use crate::attributes; use crate::generics; use crate::generics::ImplIndirection; use crate::generics::TraitDependencyMode; @@ -15,6 +14,7 @@ use crate::opt::AsyncStrategy; use crate::opt::Mockable; use crate::opt::Opts; use crate::opt::SpanOpt; +use crate::sub_attributes::SubAttribute; use crate::token_util::push_tokens; use crate::token_util::TokenPair; @@ -28,7 +28,7 @@ pub struct FnDelegationCodegen<'s, TR> { pub trait_generics: &'s generics::TraitGenerics, pub fn_input_mode: &'s FnInputMode<'s>, pub trait_dependency_mode: &'s TraitDependencyMode<'s, 's>, - pub use_associated_future: generics::UseAssociatedFuture, + pub sub_attributes: &'s [SubAttribute<'s>], } impl<'s, TR: ToTokens> FnDelegationCodegen<'s, TR> { @@ -44,11 +44,8 @@ impl<'s, TR: ToTokens> FnDelegationCodegen<'s, TR> { /// ``` /// pub fn gen_impl_block(&self, trait_fns: &[TraitFn]) -> TokenStream { - let async_trait_attribute = - attributes::opt_async_trait_attr(self.opts, self.crate_idents, trait_fns.iter()); let params = self.trait_generics.impl_params( self.trait_dependency_mode, - self.use_associated_future, generics::has_any_self_by_value(trait_fns.iter().map(|trait_fn| trait_fn.sig())), ); let args = self.trait_generics.arguments(&self.impl_indirection); @@ -82,11 +79,6 @@ impl<'s, TR: ToTokens> FnDelegationCodegen<'s, TR> { }; let items = trait_fns.iter().map(|trait_fn| { - let associated_fut_impl = &trait_fn.entrait_sig.associated_fut_impl( - self.impl_indirection.to_trait_indirection(), - self.crate_idents, - ); - let fn_item = self.gen_delegating_fn_item( trait_fn, self.trait_span, @@ -95,16 +87,21 @@ impl<'s, TR: ToTokens> FnDelegationCodegen<'s, TR> { ); quote! { - #associated_fut_impl #fn_item } }); + let trait_impl_sub_attributes = self + .sub_attributes + .iter() + .copied() + .filter(|sub_attr| matches!(sub_attr, SubAttribute::AsyncTrait(_))); + let trait_span = self.trait_span; let trait_ref = &self.trait_ref; quote_spanned! { trait_span=> - #async_trait_attribute + #(#trait_impl_sub_attributes)* impl #params #trait_ref #args for #self_ty #where_clause { #(#items)* } @@ -146,10 +143,7 @@ impl<'s, TR: ToTokens> FnDelegationCodegen<'s, TR> { }, }); - let mut opt_dot_await = trait_fn.opt_dot_await(span); - if entrait_sig.associated_fut.is_some() { - opt_dot_await = None; - } + let opt_dot_await = trait_fn.opt_dot_await(span); if trait_fn.originally_async && matches!( diff --git a/entrait_macros/src/generics.rs b/entrait_macros/src/generics.rs index bd0ce41..63033ce 100644 --- a/entrait_macros/src/generics.rs +++ b/entrait_macros/src/generics.rs @@ -3,8 +3,6 @@ use proc_macro2::TokenStream; use crate::{ analyze_generics::TraitFn, idents::GenericIdents, - input::InputFn, - opt::{AsyncStrategy, Opts, SpanOpt}, token_util::{push_tokens, EmptyToken, Punctuator, TokenPair}, }; @@ -15,16 +13,6 @@ pub enum ImplIndirection<'s> { Dynamic { ty: &'s syn::Type }, } -impl<'s> ImplIndirection<'s> { - pub fn to_trait_indirection(&'s self) -> TraitIndirection { - match self { - Self::None => TraitIndirection::Plain, - Self::Static { .. } => TraitIndirection::StaticImpl, - Self::Dynamic { .. } => TraitIndirection::DynamicImpl, - } - } -} - #[derive(Clone, Copy)] pub enum TraitIndirection { /// Normal entrait/fn, entrait/mod etc @@ -40,23 +28,6 @@ pub enum TraitIndirection { #[derive(Clone, Copy)] pub struct UseAssociatedFuture(pub bool); -pub fn detect_use_associated_future<'i>( - opts: &Opts, - input_fns: impl Iterator, -) -> UseAssociatedFuture { - UseAssociatedFuture(matches!( - ( - opts.async_strategy(), - has_any_async(input_fns.map(|input_fn| &input_fn.fn_sig)) - ), - (SpanOpt(AsyncStrategy::AssociatedFuture, _), true) - )) -} - -pub fn has_any_async<'s>(mut signatures: impl Iterator) -> bool { - signatures.any(|sig| sig.asyncness.is_some()) -} - #[derive(Clone, Copy)] pub struct TakesSelfByValue(pub bool); @@ -95,7 +66,6 @@ impl TraitGenerics { ParamsGenerator { params: &self.params, impl_t: None, - use_associated_future: UseAssociatedFuture(false), takes_self_by_value: TakesSelfByValue(false), } } @@ -109,7 +79,6 @@ impl TraitGenerics { pub fn impl_params<'i>( &'i self, trait_dependency_mode: &'i TraitDependencyMode<'i, '_>, - use_associated_future: UseAssociatedFuture, takes_self_by_value: TakesSelfByValue, ) -> ParamsGenerator<'_> { ParamsGenerator { @@ -118,7 +87,6 @@ impl TraitGenerics { TraitDependencyMode::Generic(idents) => Some(&idents.impl_t), TraitDependencyMode::Concrete(_) => None, }, - use_associated_future, takes_self_by_value, } } @@ -126,13 +94,11 @@ impl TraitGenerics { pub fn impl_params_from_idents<'i>( &'i self, idents: &'i GenericIdents, - use_associated_future: UseAssociatedFuture, takes_self_by_value: TakesSelfByValue, ) -> ParamsGenerator<'_> { ParamsGenerator { params: &self.params, impl_t: Some(&idents.impl_t), - use_associated_future, takes_self_by_value, } } @@ -195,7 +161,6 @@ impl<'g, 'c> quote::ToTokens for ImplPath<'g, 'c> { pub struct ParamsGenerator<'g> { params: &'g syn::punctuated::Punctuated, impl_t: Option<&'g syn::Ident>, - use_associated_future: UseAssociatedFuture, takes_self_by_value: TakesSelfByValue, } @@ -226,7 +191,8 @@ impl<'g> quote::ToTokens for ParamsGenerator<'g> { ); } - if self.use_associated_future.0 { + // if self.use_associated_future.0 { + if true { push_tokens!( stream, syn::token::Plus::default(), diff --git a/entrait_macros/src/lib.rs b/entrait_macros/src/lib.rs index 8ad81ad..8d88aba 100644 --- a/entrait_macros/src/lib.rs +++ b/entrait_macros/src/lib.rs @@ -19,7 +19,7 @@ mod idents; mod input; mod opt; mod signature; -mod static_async_trait; +mod sub_attributes; mod token_util; mod trait_codegen; @@ -57,21 +57,6 @@ pub fn entrait_export_use_box_futures( }) } -#[proc_macro_attribute] -pub fn entrait_use_associated_futures(attr: TokenStream, input: TokenStream) -> TokenStream { - invoke(attr, input, |opts| { - opts.set_fallback_async_strategy(AsyncStrategy::AssociatedFuture); - }) -} - -#[proc_macro_attribute] -pub fn entrait_export_use_associated_futures(attr: TokenStream, input: TokenStream) -> TokenStream { - invoke(attr, input, |opts| { - set_fallbacks([&mut opts.export]); - opts.set_fallback_async_strategy(AsyncStrategy::AssociatedFuture); - }) -} - #[proc_macro_attribute] pub fn entrait_unimock(attr: TokenStream, input: TokenStream) -> TokenStream { invoke(attr, input, |opts| { @@ -105,37 +90,6 @@ pub fn entrait_export_unimock_use_box_futures( }) } -#[proc_macro_attribute] -pub fn entrait_unimock_use_associated_futures( - attr: TokenStream, - input: TokenStream, -) -> TokenStream { - invoke(attr, input, |opts| { - set_fallbacks([&mut opts.unimock]); - opts.set_fallback_async_strategy(AsyncStrategy::AssociatedFuture); - }) -} - -#[proc_macro_attribute] -pub fn entrait_export_unimock_use_associated_futures( - attr: TokenStream, - input: TokenStream, -) -> TokenStream { - invoke(attr, input, |opts| { - set_fallbacks([&mut opts.export, &mut opts.unimock]); - opts.set_fallback_async_strategy(AsyncStrategy::AssociatedFuture); - }) -} - -#[proc_macro_attribute] -pub fn static_async_trait(_: TokenStream, input: TokenStream) -> TokenStream { - let item = syn::parse_macro_input!(input as syn::Item); - match static_async_trait::output_tokens(item) { - Ok(stream) => stream.into(), - Err(error) => error.into_compile_error().into(), - } -} - fn set_fallbacks(opts: [&mut Option>; N]) { for opt in opts.into_iter() { opt.get_or_insert(opt::SpanOpt::of(true)); diff --git a/entrait_macros/src/opt.rs b/entrait_macros/src/opt.rs index f70018c..814cd73 100644 --- a/entrait_macros/src/opt.rs +++ b/entrait_macros/src/opt.rs @@ -73,7 +73,6 @@ impl Mockable { pub enum AsyncStrategy { NoHack, BoxFuture, - AssociatedFuture, } #[derive(Clone)] diff --git a/entrait_macros/src/signature/future.rs b/entrait_macros/src/signature/future.rs index 5426ad5..2d3cf3c 100644 --- a/entrait_macros/src/signature/future.rs +++ b/entrait_macros/src/signature/future.rs @@ -1,4 +1,3 @@ -use proc_macro2::Span; use proc_macro2::TokenStream; use quote::quote; use quote::ToTokens; @@ -8,90 +7,8 @@ use crate::idents::CrateIdents; use crate::token_util::EmptyToken; use crate::token_util::Punctuator; -use super::lifetimes; use super::AssociatedFut; use super::EntraitSignature; -use super::ReceiverGeneration; -use super::SigComponent; -use super::UsedInOutput; -use super::UserProvidedLifetime; - -impl EntraitSignature { - pub fn convert_to_associated_future( - &mut self, - receiver_generation: ReceiverGeneration, - trait_span: Span, - ) { - lifetimes::de_elide_lifetimes(self, receiver_generation); - - let base_lifetime = syn::Lifetime::new("'entrait_future", Span::call_site()); - self.et_lifetimes.push(super::EntraitLifetime { - lifetime: base_lifetime.clone(), - source: SigComponent::Base, - user_provided: UserProvidedLifetime(false), - used_in_output: UsedInOutput(false), - }); - - let output = clone_output_type(&self.sig.output); - - // make the function generic if it wasn't already - let sig = &mut self.sig; - sig.asyncness = None; - let generics = &mut sig.generics; - generics.lt_token.get_or_insert(syn::parse_quote! { < }); - generics.gt_token.get_or_insert(syn::parse_quote! { > }); - - // insert generated/non-user-provided lifetimes - for fut_lifetime in self.et_lifetimes.iter().filter(|lt| !lt.user_provided.0) { - generics - .params - .push(syn::GenericParam::Lifetime(syn::LifetimeParam { - attrs: vec![], - lifetime: fut_lifetime.lifetime.clone(), - colon_token: None, - bounds: syn::punctuated::Punctuated::new(), - })); - } - - let fut_ident = quote::format_ident!("Fut__{}", sig.ident); - - let fut_lifetimes = self - .et_lifetimes_in_assoc_future() - .map(|et| &et.lifetime) - .collect::>(); - - self.sig.output = syn::parse_quote_spanned! { trait_span => - -> Self::#fut_ident<#(#fut_lifetimes),*> - }; - - let sig_where_clause = self.sig.generics.make_where_clause(); - for lifetime in &self.et_lifetimes { - if !matches!(lifetime.source, SigComponent::Base) { - let lt = &lifetime.lifetime; - - sig_where_clause.predicates.push(syn::parse_quote! { - #lt: #base_lifetime - }); - } - } - sig_where_clause.predicates.push(syn::parse_quote! { - Self: #base_lifetime - }); - - self.associated_fut = Some(AssociatedFut { - ident: fut_ident, - output, - base_lifetime, - }); - } -} - -fn clone_output_type(return_type: &syn::ReturnType) -> syn::Type { - match return_type { - syn::ReturnType::Default => syn::parse_quote! { () }, - syn::ReturnType::Type(_, ty) => ty.as_ref().clone(), - } -} pub struct FutDecl<'s> { pub signature: &'s EntraitSignature, @@ -158,25 +75,6 @@ impl<'s> ToTokens for FutImpl<'s> { } } -struct FutParams<'s> { - signature: &'s EntraitSignature, -} - -impl<'s> ToTokens for FutParams<'s> { - fn to_tokens(&self, stream: &mut TokenStream) { - let mut punctuator = Punctuator::new( - stream, - syn::token::Lt::default(), - syn::token::Comma::default(), - syn::token::Gt::default(), - ); - - for lt in self.signature.et_lifetimes_in_assoc_future() { - punctuator.push(<.lifetime); - } - } -} - struct FutWhereClause<'s> { signature: &'s EntraitSignature, trait_indirection: TraitIndirection, diff --git a/entrait_macros/src/signature/lifetimes.rs b/entrait_macros/src/signature/lifetimes.rs index 6ea31bc..8152b99 100644 --- a/entrait_macros/src/signature/lifetimes.rs +++ b/entrait_macros/src/signature/lifetimes.rs @@ -1,40 +1,10 @@ use super::{ - EntraitLifetime, EntraitSignature, ReceiverGeneration, SigComponent, UsedInOutput, - UserProvidedLifetime, + EntraitLifetime, ReceiverGeneration, SigComponent, UsedInOutput, UserProvidedLifetime, }; use std::collections::HashSet; use syn::visit_mut::VisitMut; -pub fn de_elide_lifetimes( - entrait_sig: &mut EntraitSignature, - receiver_generation: ReceiverGeneration, -) { - let mut elision_detector = ElisionDetector::new(receiver_generation); - elision_detector.detect(&mut entrait_sig.sig); - - let mut visitor = LifetimeMutVisitor::new(elision_detector.elided_params); - - match receiver_generation { - ReceiverGeneration::None => { - for (index, arg) in entrait_sig.sig.inputs.iter_mut().enumerate() { - visitor.de_elide_param(index, arg); - } - } - ReceiverGeneration::Rewrite | ReceiverGeneration::Insert => { - visitor.de_elide_receiver(entrait_sig.sig.inputs.first_mut().unwrap()); - - for (index, arg) in entrait_sig.sig.inputs.iter_mut().skip(1).enumerate() { - visitor.de_elide_param(index, arg); - } - } - } - - visitor.de_elide_output(&mut entrait_sig.sig.output); - - entrait_sig.et_lifetimes.append(&mut visitor.et_lifetimes); -} - /// Looks at elided lifetimes and makes them explicit. /// Also collects all lifetimes into `et_lifetimes`. struct LifetimeMutVisitor { diff --git a/entrait_macros/src/signature/mod.rs b/entrait_macros/src/signature/mod.rs index 0e2e88f..a4a1036 100644 --- a/entrait_macros/src/signature/mod.rs +++ b/entrait_macros/src/signature/mod.rs @@ -1,14 +1,9 @@ pub mod converter; -pub mod future; -pub mod lifetimes; mod fn_params; use std::ops::Deref; -use crate::generics::TraitIndirection; -use crate::idents::CrateIdents; - #[derive(Clone, Copy)] pub struct InputSig<'s> { sig: &'s syn::Signature, @@ -41,7 +36,6 @@ pub enum ImplReceiverKind { #[derive(Clone)] pub struct EntraitSignature { pub sig: syn::Signature, - pub associated_fut: Option, pub et_lifetimes: Vec, } @@ -49,52 +43,9 @@ impl EntraitSignature { pub fn new(sig: syn::Signature) -> Self { Self { sig, - associated_fut: None, et_lifetimes: vec![], } } - - pub fn associated_fut_decl<'s>( - &'s self, - trait_indirection: TraitIndirection, - crate_idents: &'s CrateIdents, - ) -> Option> { - self.associated_fut - .as_ref() - .map(|associated_fut| future::FutDecl { - signature: self, - associated_fut, - trait_indirection, - crate_idents, - }) - } - - pub fn associated_fut_impl<'s>( - &'s self, - trait_indirection: TraitIndirection, - crate_idents: &'s CrateIdents, - ) -> Option> { - self.associated_fut - .as_ref() - .map(|associated_fut| future::FutImpl { - signature: self, - associated_fut, - trait_indirection, - crate_idents, - }) - } - - fn et_lifetimes_in_assoc_future(&self) -> impl Iterator { - self.et_lifetimes - .iter() - .filter(|et| et.used_in_output.0 || matches!(et.source, SigComponent::Base)) - } - - fn et_lifetimes_in_assoc_future_except_base( - &self, - ) -> impl Iterator { - self.et_lifetimes.iter().filter(|et| et.used_in_output.0) - } } #[derive(Clone)] @@ -108,25 +59,8 @@ pub struct AssociatedFut { #[derive(Clone)] pub struct EntraitLifetime { pub lifetime: syn::Lifetime, - pub source: SigComponent, - pub user_provided: UserProvidedLifetime, - pub used_in_output: UsedInOutput, -} - -#[derive(Copy, Clone, Eq, PartialEq)] -pub enum SigComponent { - Receiver, - Param(usize), - Output, - Base, } -#[derive(Clone, Copy)] -pub struct UserProvidedLifetime(bool); - -#[derive(Clone, Copy)] -pub struct UsedInOutput(bool); - #[derive(Clone, Copy)] pub enum ReceiverGeneration { Insert, diff --git a/entrait_macros/src/static_async_trait/mod.rs b/entrait_macros/src/static_async_trait/mod.rs deleted file mode 100644 index 7acfbc7..0000000 --- a/entrait_macros/src/static_async_trait/mod.rs +++ /dev/null @@ -1,142 +0,0 @@ -use proc_macro2::{Span, TokenStream}; -use quote::{quote, ToTokens}; -use syn::{spanned::Spanned, ImplItemFn, ItemTrait}; - -use crate::{ - generics::TraitIndirection, - idents::CrateIdents, - signature::{EntraitSignature, ReceiverGeneration}, -}; - -pub fn output_tokens(item: syn::Item) -> syn::Result { - match item { - syn::Item::Trait(item_trait) => process_trait(item_trait), - syn::Item::Impl(item_impl) => process_impl(item_impl), - other => Err(syn::Error::new( - other.span(), - "Cannot make this static-async", - )), - } -} - -fn process_trait(item_trait: syn::ItemTrait) -> syn::Result { - let crate_idents = CrateIdents::new(item_trait.ident.span()); - let trait_span = item_trait.ident.span(); - - let ItemTrait { - attrs, - vis, - unsafety, - auto_token, - restriction: _, - trait_token, - ident, - generics, - colon_token, - supertraits, - brace_token: _, - items, - } = item_trait; - let mut new_items = TokenStream::new(); - - for item in items.into_iter() { - match item { - syn::TraitItem::Fn(method) if method.sig.asyncness.is_some() => { - let (sig, trait_indirection) = convert_sig(method.sig, trait_span); - let fut = sig.associated_fut_decl(trait_indirection, &crate_idents); - let trait_fn_sig = &sig.sig; - - quote! { - #fut - #trait_fn_sig; - } - .to_tokens(&mut new_items); - } - item => { - item.to_tokens(&mut new_items); - } - } - } - - Ok(quote! { - #(#attrs)* - #vis #unsafety #auto_token #trait_token #ident #generics #colon_token #supertraits { - #new_items - } - }) -} -fn process_impl(item_impl: syn::ItemImpl) -> syn::Result { - let syn::ItemImpl { - attrs, - defaultness, - unsafety, - impl_token, - generics, - trait_, - self_ty, - brace_token: _, - items, - } = item_impl; - - let mut new_items = TokenStream::new(); - - if trait_.is_some() { - let impl_span = impl_token.span(); - let crate_idents = CrateIdents::new(impl_token.span()); - for item in items.into_iter() { - match item { - syn::ImplItem::Fn(method) if method.sig.asyncness.is_some() => { - let ImplItemFn { - attrs, - vis, - defaultness, - sig, - block: syn::Block { stmts, .. }, - } = method; - - let (sig, trait_indirection) = convert_sig(sig, impl_span); - let fut = sig.associated_fut_impl(trait_indirection, &crate_idents); - let trait_fn_sig = &sig.sig; - - quote! { - #fut - - #(#attrs)* - #vis #defaultness #trait_fn_sig { - async move { #(#stmts)* } - } - } - .to_tokens(&mut new_items); - } - item => { - item.to_tokens(&mut new_items); - } - } - } - } else { - new_items = quote! { #(#items)* }; - } - - let trait_ = trait_.map(|(bang, path, for_)| quote! { #bang #path #for_ }); - let where_clause = &generics.where_clause; - - Ok(quote! { - #(#attrs)* - #defaultness #unsafety #impl_token #generics #trait_ #self_ty #where_clause { - #new_items - } - }) -} - -fn convert_sig(sig: syn::Signature, span: Span) -> (EntraitSignature, TraitIndirection) { - let trait_indirection = if matches!(sig.inputs.first(), Some(syn::FnArg::Receiver(_))) { - TraitIndirection::Plain - } else { - TraitIndirection::StaticImpl - }; - - let mut entrait_sig = EntraitSignature::new(sig); - entrait_sig.convert_to_associated_future(ReceiverGeneration::Rewrite, span); - - (entrait_sig, trait_indirection) -} diff --git a/entrait_macros/src/sub_attributes.rs b/entrait_macros/src/sub_attributes.rs new file mode 100644 index 0000000..daa508a --- /dev/null +++ b/entrait_macros/src/sub_attributes.rs @@ -0,0 +1,46 @@ +//! The other attributes specified _under_ entrait + +use quote::ToTokens; + +#[derive(Clone, Copy)] +pub enum SubAttribute<'t> { + AsyncTrait(&'t syn::Attribute), + Other(&'t syn::Attribute), + Automock(&'t syn::Attribute), +} + +pub fn analyze_sub_attributes(attributes: &[syn::Attribute]) -> Vec> { + attributes + .iter() + .map(|attribute| { + let last_segment = attribute.path().segments.last(); + let ident = last_segment.map(|segment| segment.ident.to_string()); + + if let Some(ident) = ident { + match ident.as_str() { + "async_trait" => SubAttribute::AsyncTrait(attribute), + "automock" => SubAttribute::Automock(attribute), + _ => SubAttribute::Other(attribute), + } + } else { + SubAttribute::Other(attribute) + } + }) + .collect() +} + +pub fn contains_async_trait(sub_attributes: &[SubAttribute]) -> bool { + sub_attributes + .iter() + .any(|sub_attributes| matches!(sub_attributes, SubAttribute::AsyncTrait(_))) +} + +impl<'t> ToTokens for SubAttribute<'t> { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + match self { + Self::AsyncTrait(attr) => attr.to_tokens(tokens), + Self::Automock(attr) => attr.to_tokens(tokens), + Self::Other(attr) => attr.to_tokens(tokens), + } + } +} diff --git a/entrait_macros/src/trait_codegen.rs b/entrait_macros/src/trait_codegen.rs index f44dc1c..e0b2aa7 100644 --- a/entrait_macros/src/trait_codegen.rs +++ b/entrait_macros/src/trait_codegen.rs @@ -1,5 +1,6 @@ use proc_macro2::{Span, TokenStream}; use quote::{quote, quote_spanned, ToTokens}; +use syn::spanned::Spanned; use crate::{ analyze_generics::TraitFn, @@ -8,6 +9,8 @@ use crate::{ idents::CrateIdents, input::FnInputMode, opt::{Opts, SpanOpt}, + signature::EntraitSignature, + sub_attributes::{contains_async_trait, SubAttribute}, token_util::push_tokens, }; @@ -16,6 +19,7 @@ pub struct TraitCodegen<'s> { pub crate_idents: &'s CrateIdents, pub trait_indirection: TraitIndirection, pub trait_dependency_mode: &'s TraitDependencyMode<'s, 's>, + pub sub_attributes: &'s [SubAttribute<'s>], } impl<'s> TraitCodegen<'s> { @@ -62,29 +66,16 @@ impl<'s> TraitCodegen<'s> { }), _ => None, }; - let opt_async_trait_attr = - attributes::opt_async_trait_attr(self.opts, self.crate_idents, trait_fns.iter()); - - let literal_attrs = if let FnInputMode::RawTrait(literal_attrs) = fn_input_mode { - Some(literal_attrs) - } else { - None - }; - let trait_visibility = TraitVisibility { visibility, fn_input_mode, }; let fn_defs = trait_fns.iter().map(|trait_fn| { - let opt_associated_fut_decl = &trait_fn - .entrait_sig - .associated_fut_decl(self.trait_indirection, self.crate_idents); let attrs = &trait_fn.attrs; - let trait_fn_sig = trait_fn.sig(); + let trait_fn_sig = make_trait_fn_sig(&trait_fn.entrait_sig, self.sub_attributes); quote! { - #opt_associated_fut_decl #(#attrs)* #trait_fn_sig; } @@ -93,12 +84,18 @@ impl<'s> TraitCodegen<'s> { let params = trait_generics.trait_params(); let where_clause = trait_generics.trait_where_clause(); + let trait_sub_attributes = self.sub_attributes.iter().filter(|attr| { + matches!( + attr, + SubAttribute::AsyncTrait(_) | SubAttribute::Automock(_) + ) + }); + Ok(quote_spanned! { span=> #opt_unimock_attr #opt_entrait_for_trait_attr #opt_mockall_automock_attr - #opt_async_trait_attr - #literal_attrs + #(#trait_sub_attributes)* #trait_visibility trait #trait_ident #params #supertraits #where_clause { #(#fn_defs)* } @@ -159,3 +156,30 @@ impl<'a> ToTokens for TraitVisibility<'a> { } } } + +fn make_trait_fn_sig( + entrait_sig: &EntraitSignature, + sub_attributes: &[SubAttribute], +) -> syn::Signature { + let mut sig = entrait_sig.sig.clone(); + + if entrait_sig.sig.asyncness.is_some() && !contains_async_trait(sub_attributes) { + sig.asyncness = None; + + let mut return_type = syn::ReturnType::Default; + std::mem::swap(&mut return_type, &mut sig.output); + + let span = return_type.span(); + + let output_type: syn::Type = match return_type { + syn::ReturnType::Default => syn::parse_quote! { () }, + syn::ReturnType::Type(_, ty) => *ty, + }; + + sig.output = syn::parse_quote_spanned! {span=> + -> impl ::core::future::Future + ::core::marker::Send + }; + } + + sig +} diff --git a/examples/async-graphql/Cargo.toml b/examples/async-graphql/Cargo.toml index 657302e..e4e7349 100644 --- a/examples/async-graphql/Cargo.toml +++ b/examples/async-graphql/Cargo.toml @@ -16,4 +16,4 @@ tower = "0.4" tower-http = { version = "0.3", features = ["trace"] } hyper = { version = "0.14", features = ["full"] } serde_json = "1" -unimock = "0.6" +unimock = "0.6.1" diff --git a/examples/async-graphql/src/main.rs b/examples/async-graphql/src/main.rs index 78f4bdf..72473db 100644 --- a/examples/async-graphql/src/main.rs +++ b/examples/async-graphql/src/main.rs @@ -1,7 +1,7 @@ mod db { use entrait::*; - #[entrait(pub FetchSomeValue, no_deps, box_future, mock_api=FetchSomeValueMock)] + #[entrait(pub FetchSomeValue, no_deps, mock_api=FetchSomeValueMock)] async fn fetch_some_value() -> String { "real".to_string() } diff --git a/examples/axum/Cargo.toml b/examples/axum/Cargo.toml index 2f0438a..71ef39d 100644 --- a/examples/axum/Cargo.toml +++ b/examples/axum/Cargo.toml @@ -17,4 +17,4 @@ tower = "0.4" tower-http = { version = "0.3", features = ["trace"] } hyper = { version = "0.14", features = ["full"] } serde_json = "1" -unimock = "0.6" +unimock = "0.6.1" diff --git a/examples/axum/src/main.rs b/examples/axum/src/main.rs index af0e25e..da62a8f 100644 --- a/examples/axum/src/main.rs +++ b/examples/axum/src/main.rs @@ -11,7 +11,7 @@ pub struct Foo { mod business { use super::*; - #[entrait(pub GetFoo, no_deps, box_future, mock_api=GetFooMock)] + #[entrait(pub GetFoo, no_deps, mock_api=GetFooMock)] async fn get_foo() -> Foo { Foo { value: "real".to_string(), diff --git a/src/lib.rs b/src/lib.rs index 2be8c45..2217f73 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -959,8 +959,3 @@ pub use ::unimock as __unimock; pub mod __async_trait { pub use ::async_trait::async_trait; } - -#[doc(hidden)] -pub mod static_async { - pub use entrait_macros::static_async_trait as async_trait; -} diff --git a/tests/it/delegation_modes.rs b/tests/it/delegation_modes.rs index 6df43db..24abb0a 100644 --- a/tests/it/delegation_modes.rs +++ b/tests/it/delegation_modes.rs @@ -39,18 +39,17 @@ mod borrow_dyn_sync { } } -#[cfg(feature = "boxed-futures")] mod borrow_dyn_use_boxed_futures { use super::*; use async_trait::*; use entrait::*; - #[entrait(Foo, box_future)] + #[entrait(Foo)] async fn foo(deps: &impl Bar) { deps.bar().await; } - #[entrait(delegate_by=ref, box_future)] + #[entrait(delegate_by=ref)] #[async_trait] trait Bar: Sync + 'static { async fn bar(&self); diff --git a/tests/it/dependency_inversion.rs b/tests/it/dependency_inversion.rs index 278640f..03ec2a6 100644 --- a/tests/it/dependency_inversion.rs +++ b/tests/it/dependency_inversion.rs @@ -92,7 +92,6 @@ mod simple_dyn { } } -#[cfg(feature = "nightly-tests")] mod async_static { use entrait::*; @@ -128,11 +127,11 @@ mod async_static { } } -#[cfg(any(feature = "boxed-futures"))] mod async_dyn { use entrait::*; - #[entrait(FoobarImpl, delegate_by=ref, box_future)] + #[entrait(FoobarImpl, delegate_by=ref)] + #[async_trait::async_trait] pub trait Foobar { async fn foo(&self) -> i32; async fn bar(&self) -> u32; @@ -141,6 +140,7 @@ mod async_dyn { pub struct Implementor2; #[entrait(ref)] + #[async_trait::async_trait] impl FoobarImpl for Implementor2 { pub async fn bar(_: &D) -> u32 { 1337 diff --git a/tests/it/main.rs b/tests/it/main.rs index 90b34aa..59cbbea 100644 --- a/tests/it/main.rs +++ b/tests/it/main.rs @@ -1,6 +1,6 @@ #![allow(dead_code)] #![allow(unused)] -#![allow(clippy::blacklisted_name)] +#![allow(clippy::disallowed_names)] #![cfg_attr( any(feature = "nightly-tests", feature = "use-associated-futures"), feature(type_alias_impl_trait) diff --git a/tests/it/simple.rs b/tests/it/simple.rs index 5214e2e..d179465 100644 --- a/tests/it/simple.rs +++ b/tests/it/simple.rs @@ -82,11 +82,6 @@ mod bounds { } } -#[cfg(any( - feature = "use-boxed-futures", - feature = "use-associated-futures", - feature = "nightly-tests" -))] mod no_deps_and_feign { use entrait::entrait; @@ -192,7 +187,7 @@ mod module { not_included(); } - static S: &'static str = ""; + static S: &str = ""; fn not_included() {} } diff --git a/tests/it/unimock.rs b/tests/it/unimock.rs index 450dbf3..9188975 100644 --- a/tests/it/unimock.rs +++ b/tests/it/unimock.rs @@ -1,6 +1,8 @@ #![allow(dead_code)] #![allow(unused_variables)] +use std::future::Future; + mod sync { use entrait::*; @@ -15,11 +17,10 @@ mod sync { } } -#[cfg(any( - feature = "use-boxed-futures", - feature = "use-associated-futures", - feature = "nightly-tests" -))] +trait Lol { + fn hei(&self) -> impl Future + Send; +} + mod auth { use entrait::*; use unimock::*; @@ -121,11 +122,6 @@ mod auth { } } -#[cfg(any( - feature = "use-boxed-futures", - feature = "use-associated-futures", - feature = "nightly-tests" -))] mod multi_mock { use entrait::*; use unimock::*; @@ -211,8 +207,9 @@ mod multi_mock { /// Note: This test does not run under "nightly-tests", /// because it uses tokio::spawn, and there is currently /// no way to Send-bound futures from plain async fns in traits. -#[cfg(any(feature = "use-boxed-futures", feature = "use-associated-futures"))] mod tokio_spawn { + use std::future::Future; + use entrait::*; use unimock::*; @@ -260,11 +257,6 @@ mod tokio_spawn { } } -#[cfg(any( - feature = "use-boxed-futures", - feature = "use-associated-futures", - feature = "nightly-tests" -))] mod more_async { use entrait::*; use unimock::*; @@ -305,11 +297,6 @@ mod more_async { } } -#[cfg(any( - feature = "use-boxed-futures", - feature = "use-associated-futures", - feature = "nightly-tests" -))] mod async_no_deps_etc { use entrait::*; use unimock::*; @@ -540,11 +527,6 @@ mod module { } } -#[cfg(any( - feature = "use-boxed-futures", - feature = "use-associated-futures", - feature = "nightly-tests" -))] mod module_async { use entrait::*;