Hello!
I'm trying to utilize Iterable
trait:
use std::ops::Deref;
trait Iterable {
type Item<'a> where Self: 'a;
type Iter<'a>: Iterator<Item = Self::Item<'a>> where Self: 'a;
fn iter<'a>(&'a self) -> Self::Iter<'a>;
}
trait Set<T>: Iterable
where
for<'a> <Self as Iterable>::Item<'a>: Deref<Target = T>
{ }
trait Types {
type Set: Set<i32>;
}
fn main() {
}
Unfortunately, I receive compilation error:
error[E0277]: the trait bound `for<'a> <<Self as Types>::Set as Iterable>::Item<'a>: Deref` is not satisfied
--> src/main.rs:16:15
|
16 | type Set: Set<i32>;
| ^^^^^^^^ the trait `for<'a> Deref` is not implemented for `<<Self as Types>::Set as Iterable>::Item<'a>`
|
note: required by a bound in `Set`
--> src/main.rs:12:43
|
10 | trait Set<T>: Iterable
| --- required by a bound in this
11 | where
12 | for<'a> <Self as Iterable>::Item<'a>: Deref<Target = T>
| ^^^^^^^^^^^^^^^^^ required by this bound in `Set`
If I modify Types
according to recommendations:
use std::ops::Deref;
trait Iterable {
type Item<'a> where Self: 'a;
type Iter<'a>: Iterator<Item = Self::Item<'a>> where Self: 'a;
fn iter<'a>(&'a self) -> Self::Iter<'a>;
}
trait Set<T>: Iterable
where
for<'a> <Self as Iterable>::Item<'a>: Deref<Target = T>
{ }
trait Types {
type Set: Set<i32>
where
for<'a> <<Self as Types>::Set as Iterable>::Item<'a>: Deref<Target = i32>;
}
fn main() {
}
it works, but extremely ugly, I can't even move Deref
requirement to generics block, where it would be much more readable
Meanwhile, following variant:
use std::ops::Deref;
trait Iterable<T> {
type Item<'a>: Deref<Target = T> where Self: 'a;
type Iter<'a>: Iterator<Item = Self::Item<'a>> where Self: 'a;
fn iter<'a>(&'a self) -> Self::Iter<'a>;
}
trait Set<T>: Iterable<T>
{ }
trait Types {
type Set: Set<i32>;
}
fn main() {
}
works just fine, but isn't suitable since Deref
bound is moved to Iterable
declaration.
Any ideas what to do with first variant to make it not require lengthy bound at the usage spot?
Thanks
EDIT:
I thought it's caused by generic bound moved to associated type and tried this:
use std::ops::Deref;
trait Iterable {
type Item<'a> where Self: 'a;
type Iter<'a>: Iterator<Item = Self::Item<'a>> where Self: 'a;
fn iter<'a>(&'a self) -> Self::Iter<'a>;
}
trait Set: Iterable
where
for<'a> <Self as Iterable>::Item<'a>: Deref<Target = <Self as Set>::Elem>
{
type Elem;
}
trait Types {
type Set: Set<Elem = i32>;
}
fn main() {
}
Sadly, still no luck. The only way I found is to merge Iterable
into Set
and declare Item
, Iter
and fn iter
in Set
trait.