Open Dante-Broggi opened 1 year ago
The only things implied by a trait bound are other Self: Trait
bounds, either in the supertraits (trait A: B + C
) or in where clauses (trait A where Self: B
).
@rustbot label A-traits
I tried to workaround by introducing a helper trait with effective bounds on its associated types, but got more strange behaviors:
trait Super {
type Assoc;
}
trait Helper {
type AssocHelper: Into<u64>;
}
impl<T> Helper for T
where
T: Super,
T::Assoc: Into<u64>,
{
type AssocHelper = T::Assoc;
}
trait Derived: Super + Helper<AssocHelper = Self::Assoc> {}
fn use_assoc_bounds<T: Derived>(x: T::Assoc) -> u64 {
// x.into() // not working, somehow.
helper::<T>(x) // works.
}
fn helper<T: Helper>(x: T::AssocHelper) -> u64 {
x.into()
}
To provide some motivation for code in the pattern above, some example is like this:
pub trait Animal {
type Mouth: Mouth;
fn mouth(&self) -> Self::Mouth;
}
pub trait Bird: Animal
where
Self::Mouth: Beak,
{
}
pub trait Mouth {}
pub trait Beak: Mouth {}
fn feed<T>(animal: T)
where
T: Bird,
{ todo!() }
Implementations of Bird
may return an adapter object that implements Mouth + Beak
, which can be consistently retrieved through mouth()
. Because of the E0277 limitation, now I have to expose a separate associated function beak()
, which rsults in some less consistent API.
I thought there was some other thread about this, but I couldn't find it. It's not #113195 that I have in mind.
I tried this code:
I expected to see this happen: It compile
Instead, this happened:
Meta
Playground (rust 1.69.0 on May 24 2023), and
rustc --version --verbose
: