Open gdesmott opened 7 months ago
Here is a standalone version of the problem for easier testing:
trait Downgrade
where
Self: Sized,
{
type Weak: Upgrade;
fn downgrade(&self) -> Self::Weak;
}
trait Upgrade
where
Self: Sized,
{
type Strong;
fn upgrade(&self) -> Option<Self::Strong>;
}
trait Mytrait: Downgrade {
fn mushroom(&self) {
let weak = self.downgrade();
let this = weak.upgrade().unwrap();
this.snake();
}
fn snake(&self) {}
}
fn main() {}
Library-level, the signature for (see below)Downgrade
could be changed to have type Weak: Upgrade<Strong = Self>;
instead of just type Weak: Upgrade;
. (Are there are any cases where Self::Weak::Strong
isn't Self
?)
As for user-level workarounds, you can add a where Self::Weak: Upgrade<Strong = Self>
to your trait, e.g.
trait Mytrait: Downgrade where Self::Weak: Upgrade<Strong = Self> {
fn mushroom(&self) {
let weak = self.downgrade();
let this: Self = weak.upgrade().unwrap();
this.snake();
}
fn snake(&self) {}
}
Ah, no the library-level change won't work (as-is at least), since &T where T: Downgrade
implements Downgrade
, and you obviously can't get a &T
back out of that.
fails with:
I tried adding a bound tying back
Upgrade::Strong
with the trait but that doesn't work either:Is there a way to make this work easily?