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
.
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
}