gtk-rs-core
gtk-rs-core copied to clipboard
`Dowgrade/Upgrade` not ususable in traits
trait Mytrait: Downgrade {
fn mushroom(&self) {
let weak = self.downgrade();
let this = weak.upgrade().unwrap();
this.snake();
}
fn snake(&self) {}
}
fails with:
error[E0599]: no method named `snake` found for associated type `<<Self as Downgrade>::Weak as Upgrade>::Strong` in the current scope
--> glib/src/clone.rs:116:14
|
116 | this.snake();
| ^^^^^ method not found in `<<Self as Downgrade>::Weak as Upgrade>::Strong`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Mytrait` defines an item `snake`, perhaps you need to implement it
--> glib/src/clone.rs:112:1
|
112 | trait Mytrait: Downgrade {
| ^^^^^^^^^^^^^^^^^^^^^^^^
I tried adding a bound tying back Upgrade::Strong
with the trait but that doesn't work either:
trait Mytrait: Downgrade
where
<<Self as Downgrade>::Weak as Upgrade>::Strong: Mytrait,
{
fn mushroom(&self) {
let weak = self.downgrade();
let this = weak.upgrade().unwrap();
this.snake();
}
fn snake(&self) {}
}
error[E0277]: the trait bound `<<<<Self as Downgrade>::Weak as Upgrade>::Strong as Downgrade>::Weak as Upgrade>::Strong: Mytrait` is not satisfied
--> glib/src/clone.rs:114:53
|
114 | <<Self as Downgrade>::Weak as Upgrade>::Strong: Mytrait,
| ^^^^^^^ the trait `Mytrait` is not implemented for `<<<<Self as Downgrade>::Weak as Upgrade>::Strong as Downgrade>::Weak as Upgrade>::Strong`
|
note: required by a bound in `Mytrait`
--> glib/src/clone.rs:114:53
|
112 | trait Mytrait: Downgrade
| ------- required by a bound in this trait
113 | where
114 | <<Self as Downgrade>::Weak as Upgrade>::Strong: Mytrait,
| ^^^^^^^ required by this bound in `Mytrait`
= note: `Mytrait` is a "sealed trait", because to implement it you also need to implement `clone::Mytrait`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it
help: consider further restricting the associated type
|
114 | <<Self as Downgrade>::Weak as Upgrade>::Strong: Mytrait, <<<<Self as Downgrade>::Weak as Upgrade>::Strong as Downgrade>::Weak as Upgrade>::Strong: Mytrait
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Is there a way to make this work easily?
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 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
?)~~ (see below)
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.
errors when applying the naive change to `glib`
error[E0271]: type mismatch resolving `<<T as Downgrade>::Weak as Upgrade>::Strong == &T`
--> glib/src/clone.rs:57:17
|
56 | impl<T: Downgrade> Downgrade for &T {
| - found this type parameter
57 | type Weak = T::Weak;
| ^^^^^^^ expected `&T`, found type parameter `T`
|
= note: expected reference `&_`
found type parameter `_`
note: required by a bound in `Downgrade::Weak`
--> glib/src/clone.rs:18:24
|
18 | type Weak: Upgrade<Strong = Self>;
| ^^^^^^^^^^^^^ required by this bound in `Downgrade::Weak`
error[E0271]: type mismatch resolving `<<T as Downgrade>::Weak as Upgrade>::Strong == BorrowedObject<'a, T>`
--> glib/src/object.rs:4426:17
|
4423 | impl<'a, T: crate::clone::Downgrade + ObjectType> crate::clone::Downgrade
| - found this type parameter
...
4426 | type Weak = <T as crate::clone::Downgrade>::Weak;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `BorrowedObject<'_, T>`, found type parameter `T`
|
= note: expected struct `BorrowedObject<'a, T>`
found type parameter `T`
note: required by a bound in `Downgrade::Weak`
--> glib/src/clone.rs:18:24
|
18 | type Weak: Upgrade<Strong = Self>;
| ^^^^^^^^^^^^^ required by this bound in `Downgrade::Weak`
error[E0271]: type mismatch resolving `<ObjectImplWeakRef<BoxedAnyObject> as Upgrade>::Strong == BoxedAnyObject`
--> glib/src/boxed_any_object.rs:37:5
|
37 | #[glib::object_subclass]
| ^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<ObjectImplWeakRef<BoxedAnyObject> as Upgrade>::Strong == BoxedAnyObject`
|
note: expected this to be `imp::BoxedAnyObject`
--> glib/src/subclass/object_impl_ref.rs:157:19
|
157 | type Strong = ObjectImplRef<T>;
| ^^^^^^^^^^^^^^^^
= note: expected struct `imp::BoxedAnyObject`
found struct `ObjectImplRef<imp::BoxedAnyObject>`
note: required by a bound in `Downgrade::Weak`
--> glib/src/clone.rs:18:24
|
18 | type Weak: Upgrade<Strong = Self>;
| ^^^^^^^^^^^^^ required by this bound in `Downgrade::Weak`
= note: this error originates in the attribute macro `glib::object_subclass` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0271`.
error: could not compile `glib` (lib) due to 3 previous errors
warning: build failed, waiting for other jobs to finish...
error: could not compile `glib` (lib) due to 3 previous errors