I'm trying to make a type alias for a group of traits with associated types. However, my alias works in the opposite way, i.e., it requires the bounds to be satisfied wherever it's used.
A minimized example similar to the situation is as follows. I want to create an alias for the trait Foo whenever its type A can be created from a u8:
trait Foo {
type A;
fn foo(&self, a: Self::A);
}
trait Alias: Foo
where
<Self as Foo>::A: From<u8>,
{
}
impl<T> Alias for T
where
T: Foo,
<T as Foo>::A: From<u8>,
{
}
When I want to use this alias in the function `test:
fn test<T: Alias>(x: &T, y: u8) {
x.foo(y.into());
}
the compiler complains:
error[E0277]: the trait bound `<T as Foo>::A: From<u8>` is not satisfied
--> src/lib.rs:20:12
|
20 | fn test<T: Alias>(x: &T, y: u8) {
| ^^^^^ the trait `From<u8>` is not implemented for `<T as Foo>::A`
|
note: required by a bound in `Alias`
--> src/lib.rs:9:23
|
7 | trait Alias: Foo
| ----- required by a bound in this trait
8 | where
9 | <Self as Foo>::A: From<u8>,
| ^^^^^^^^ required by this bound in `Alias`
help: consider further restricting the associated type
|
20 | fn test<T: Alias>(x: &T, y: u8) where <T as Foo>::A: From<u8> {
| +++++++++++++++++++++++++++++
that means I should add the constraint <T as Foo>::A: From<u8> as well, which I want to avoid.
Which part I'm doing wrong? If it is a limitation in the compiler, is there any way to achieve the same behavior?
This works if you also make a type in the new trait.
trait Alias: Foo {
type AliasA: From<u8>;
}
impl<T> Alias for T
where
T: Foo,
<T as Foo>::A: From<u8>,
{
type AliasA = T::A;
}
Then just replace any usage of T::A with T::AliasA.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With