This almost works (in nightly): https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=332ca47a9d3618a8427ae618f0a8b188
#![feature(non_lifetime_binders)]
trait Foo {}
trait HasAssoc {
type Assoc<T>;
}
trait HasFooAssoc: for<T> HasAssoc<Assoc<T>: Foo> {}
struct X;
struct Y<T>(T);
impl<T> Foo for Y<T> {}
impl HasAssoc for X {
type Assoc<T> = Y<T>;
}
impl HasFooAssoc for X {}
I’m trying to define HasFooAssoc
, which is a HasAssoc
where Assoc: Foo
is known to hold. From my reading of the errors, it seems like the problem is that for<T>
has to also hold for T: ?Sized
, and I’m not syntactically allowed to type for<T: Sized>
(T actually should be Sized for my use case).
Note that if the Foo
bound is hardcoded into HasAssoc
, there is no problem: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=e6f7ec36babd27e0e160c023052be4c3
trait Foo {}
trait HasAssoc {
type Assoc<T>: Foo;
}
struct X;
struct Y<T>(T);
impl<T> Foo for Y<T> {}
impl HasAssoc for X {
type Assoc<T> = Y<T>;
}
but I would really like to add that bound in afterwards for abstraction purposes (I want e.g. both HasFooAssoc
and HasBarAssoc
, and I’d like to have the HasAssoc
part factored out, because in the real use case it’s more complex).