So, I tried to use new trait_variant
crate for working with async traits (as recommended in the announcement), and I encountered an issue with traits that appears with generic types. In particular, conflicts of trait impls arise.
Code that compiles (and uses the traits) as intended:
#[trait_variant::make(SomeTrait: Send)]
trait LocalSomeTrait {
async fn foo();
}
struct SomeStruct;
impl LocalSomeTrait for SomeStruct {
async fn foo() {}
}
adding generic parameter to the trait breaks the code:
#[trait_variant::make(SomeTrait: Send)]
trait LocalSomeTrait<T> {
async fn foo();
}
struct SomeStruct;
impl<T> LocalSomeTrait<T> for SomeStruct {
async fn foo() {}
}
compiler diagnostic is:
error[E0119]: conflicting implementations of trait `LocalSomeTrait<_>` for type `SomeStruct`
--> src/main.rs:1:1
|
1 | #[trait_variant::make(SomeTrait: Send)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `SomeStruct`
...
8 | impl<T> LocalSomeTrait<T> for SomeStruct {
| ---------------------------------------- first implementation here
|
= note: downstream crates may implement trait `SomeTrait<_>` for type `SomeStruct`
= note: this error originates in the attribute macro `trait_variant::make` (in Nightly builds, run with -Z macro-backtrace for more info)
macro expansion:
// Recursive expansion of make macro
// ==================================
#[allow(async_fn_in_trait)]
trait LocalSomeTrait<T> {
async fn foo();
}
trait SomeTrait<T>: Send {
fn foo() -> impl ::core::future::Future<Output = ()> + Send;
}
impl<T, TraitVariantBlanketType: SomeTrait<T>> LocalSomeTrait<T> for TraitVariantBlanketType {
async fn foo() {
<Self as SomeTrait<T>>::foo().await
}
}
My reasoning is that the generated implementation should not be accounted for, as my struct does not implement SomeTrait
. However, compiler seems to disagree.
I tried to search similar issues, but only found ones related to associated types. Is this some compiler issue?