From e0ddca95533b061ad1d57307785e56ecb839ea90 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Sun, 17 Dec 2023 21:11:48 -0600 Subject: [PATCH 1/2] allow(async_fn_in_trait) on traits with Send variant --- trait-variant/examples/variant.rs | 11 +++++++++-- trait-variant/src/variant.rs | 22 ++++++++++++++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/trait-variant/examples/variant.rs b/trait-variant/examples/variant.rs index 93c2ebe..5be07ef 100644 --- a/trait-variant/examples/variant.rs +++ b/trait-variant/examples/variant.rs @@ -10,8 +10,8 @@ use std::future::Future; use trait_variant::make_variant; -#[make_variant(SendIntFactory: Send)] -trait IntFactory { +#[make_variant(IntFactory: Send)] +pub trait LocalIntFactory { const NAME: &'static str; type MyFut<'a>: Future @@ -24,4 +24,11 @@ trait IntFactory { fn another_async(&self, input: Result<(), &str>) -> Self::MyFut<'_>; } +#[allow(dead_code)] +fn spawn_task(factory: impl IntFactory + 'static) { + tokio::spawn(async move { + let _int = factory.make(1, "foo").await; + }); +} + fn main() {} diff --git a/trait-variant/src/variant.rs b/trait-variant/src/variant.rs index 1a5bd1f..494a70c 100644 --- a/trait-variant/src/variant.rs +++ b/trait-variant/src/variant.rs @@ -56,15 +56,29 @@ pub fn make_variant( let attrs = parse_macro_input!(attr as Attrs); let item = parse_macro_input!(item as ItemTrait); + let maybe_allow_async_lint = if attrs + .variant + .bounds + .iter() + .any(|b| b.path.segments.last().unwrap().ident.to_string() == "Send") + { + quote! { #[allow(async_fn_in_trait)] } + } else { + quote! {} + }; + let variant = mk_variant(&attrs, &item); let blanket_impl = mk_blanket_impl(&attrs, &item); - let output = quote! { + + quote! { + #maybe_allow_async_lint #item + #variant - #blanket_impl - }; - output.into() + #blanket_impl + } + .into() } fn mk_variant(attrs: &Attrs, tr: &ItemTrait) -> TokenStream { From 956123d2ecdffaec49ed6424d713abeb0e4e4dc1 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Sun, 17 Dec 2023 22:37:55 -0600 Subject: [PATCH 2/2] Shorten name to trait_variant::make --- README.md | 8 ++++---- trait-variant/examples/variant.rs | 4 +--- trait-variant/src/lib.rs | 4 ++-- trait-variant/src/variant.rs | 2 +- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index f95a4eb..d2a3e44 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,12 @@ Utilities for working with impl traits in Rust. -## `make_variant` +## `trait_variant` -`make_variant` generates a specialized version of a base trait that uses `async fn` and/or `-> impl Trait`. For example, if you want a `Send`able version of your trait, you'd write: +`trait_variant` generates a specialized version of a base trait that uses `async fn` and/or `-> impl Trait`. For example, if you want a `Send`able version of your trait, you'd write: ```rust -#[trait_variant::make_variant(SendIntFactory: Send)] +#[trait_variant::make(SendIntFactory: Send)] trait IntFactory { async fn make(&self) -> i32; // ..or.. @@ -22,7 +22,7 @@ Implementers of the trait can choose to implement the variant instead of the ori ## `trait_transformer` -`trait_transformer` does the same thing as `make_variant`, but using experimental nightly-only syntax that depends on the `return_type_notation` feature. It may be used to experiment with new kinds of trait transformations in the future. +`trait_transformer` does the same thing as `make`, but using experimental nightly-only syntax that depends on the `return_type_notation` feature. It may be used to experiment with new kinds of trait transformations in the future. #### License and usage notes diff --git a/trait-variant/examples/variant.rs b/trait-variant/examples/variant.rs index 5be07ef..9c15409 100644 --- a/trait-variant/examples/variant.rs +++ b/trait-variant/examples/variant.rs @@ -8,9 +8,7 @@ use std::future::Future; -use trait_variant::make_variant; - -#[make_variant(IntFactory: Send)] +#[trait_variant::make(IntFactory: Send)] pub trait LocalIntFactory { const NAME: &'static str; diff --git a/trait-variant/src/lib.rs b/trait-variant/src/lib.rs index 2694318..f651249 100644 --- a/trait-variant/src/lib.rs +++ b/trait-variant/src/lib.rs @@ -20,9 +20,9 @@ pub fn trait_transformer( } #[proc_macro_attribute] -pub fn make_variant( +pub fn make( attr: proc_macro::TokenStream, item: proc_macro::TokenStream, ) -> proc_macro::TokenStream { - variant::make_variant(attr, item) + variant::make(attr, item) } diff --git a/trait-variant/src/variant.rs b/trait-variant/src/variant.rs index 494a70c..74efcc1 100644 --- a/trait-variant/src/variant.rs +++ b/trait-variant/src/variant.rs @@ -49,7 +49,7 @@ impl Parse for MakeVariant { } } -pub fn make_variant( +pub fn make( attr: proc_macro::TokenStream, item: proc_macro::TokenStream, ) -> proc_macro::TokenStream {