At present, one must fully specify any associated types and constants in trait object types, which makes sense for cases like dyn Deref<Target=Foo>
. Increasingly however, there exist cases where this fragments trait objects and necessitates separate type erased traits.
We already suppress non-object-safe methods with a where Self: Sized
bound from trait objects. I'd therefore propose we support this mechanism for associated types and constants (and statics if they happen).
As an example, this trait becomes object safe:
pub trait Foo {
const Baz : usize = 32
where Self: Sized;
type Bar = [u8; Self::Baz]
where Self: Sized;
fn foo(&self, stuff: &[u8; Self::Baz]) -> Self::Bar
where Self: Sized;
fn fooo(&self, stuff: &[u8]) -> Box<[u8]> {
Box::new(self.foo(array_ref![stuff,0,Self::Baz]))
}
}
A priori, we would not support dyn Foo<Baz=32>
under this situation because dyn Foo
knows nothing about Baz
, but we could discuss this detail further.