Search code examples
genericsrusttraitsconst-generics

Implementing a trait for all types implementing a trait with const parameter


I believe that the following code makes sense:

trait FooConst<const N: usize> {}
trait Foo {}

impl<T: FooConst<N>, const N: usize> Foo for T {}

However when I try to compile it I get error E0207 stating that the parameter N is unbounded. I don't understand why, since it seems to me that it's part of the bound on T.

Playground link


Solution

  • The fundamental reason why this is not allowed is because the trait bounds may cause multiple trait implementations for the same type.

    For example, consider a type Bar that implements both FooConst<1> and FooConst<2>, which is perfectly fine:

    struct Bar;
    
    impl FooConst<1> for Bar {}
    impl FooConst<2> for Bar {}
    

    If Foo is implemented for all T: FooConst<N>, then we get two Foo implementations for Bar: one for N == 1 and one for N == 2. Rust does not allow the possibility of having multiple trait implementations, which is why it disallows using type parameters in this way.

    One way to work around this is to instead make N an associated constant:

    trait FooConst {
        const N: usize;
    }
    trait Foo {}
    
    impl<T: FooConst> Foo for T {
        // T::N is an associated constant   
    }