If I write this code, I have the nice property that because asdf
knows T: Bar
, it automatically knows T: Foo
as well, and I don’t have to repeat it, because Bar: Foo
trait Foo {
fn foo(&self) {}
}
trait Bar where Self: Foo {}
// works!!
fn asdf<T: Bar>(x: T) { x.foo() }
however, sometimes I want to know that if a type implements a certain trait, then a related type implements a different trait. For example
trait Baz {
fn baz(&self) {}
}
trait Quux: Sized where Option<Self>: Baz {}
impl<T> Quux for T where Option<T>: Baz {}
// doesn't work!! Even if the body is deleted.
fn hjkl<T: Quux>(x: T) { Some(x).baz() }
by having the where Option<Self>: Baz
bound, I’m trying to express that “anywhere I have T: Quux
, I also know that Option<T>: Baz
“. This is analogous to the above case, where “anywhere that I have T: Bar
, I also know that T: Baz
“.
However in practice it works in the opposite direction. Instead of getting Option<T>: Baz
for free at use sites (e.g., fn hjkl
), I’m required to provide it as an additional bound.
What is going on here, and is there a way to bundle up related constraints in the way that I’m aiming for?
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b280ca1a57e5207bcf20bf880bc7dcc6