Conflicting implementations of trait with generic parameters

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?

The missing piece of this assertion is the <T> and you cannot claim that your struct does not implement SomeTrait<T> for all T. While you may not have provided any implementations yourself, as the compiler message (note: downstream crates may implement trait `SomeTrait<_>` for type `SomeStruct` ) explains, a downstream crate can impl SomeTrait<DownstreamType> for SomeStruct.

1 Like