Confusion on syntax for supertraits

Hello :waving_hand:, I have a basic data structure that behaves much like a vector (with a few key differences that prohibits using actual vectors, hashsets or treesets). Since it's such a basic building block of the computation I would like to easily swap different implementations. So a trait is the obvious answer.
Something like:

pub trait BasicStruct: Clone + Eq + Ord +  Default + IntoIterator
{
	fn is_subset(&self, other: &Self) -> bool;
	fn is_disjoint(&self, other: &Self) -> bool;
	fn union(&self, other: &Self) -> Self;
	fn extend(&self, other: &Self) -> Self;
	fn intersection(&self, other: &Self) -> Self;
	fn subtraction(&self, other: &Self) -> Self;
	fn len(&self) -> usize;
	fn is_empty(&self) -> bool;
	...
}

But I'm not satisfied with just IntoIterator, I need iter() to be implemented.
Since there is no trait for that, I need to qualify IntoIterator for &Self somehow.
What is the syntax? Can i actually do it or should i just require fn iter(...) -> ... in my trait?

You can implement IntoIterator for &T—if T is a local type—if that's what you mean.

struct MyVec(Vec<u8>);

impl<'a> IntoIterator for &'a MyVec {
    type Item = &'a u8;
    type IntoIter = std::slice::Iter<'a, u8>;
    
    fn into_iter(self) -> Self::IntoIter {
        self.0.iter()
    }
}

for example.

No, i can implement it yes, but i would like it required in the trait.
Like:

pub trait BasicStruct: ... + IntoIterator + IntoIterator for &Self
{
	...
}
trait BorrowIter<'a> {
    type Item;
    type IntoIter: Iterator<Item = Self::Item>;
    fn iter(&'a self) -> Self::IntoIter;
}
impl<'a, T: 'a> BorrowIter<'a> for T where &'a T: IntoIterator {
    type Item = <&'a T as IntoIterator>::Item;
    type IntoIter = <&'a T as IntoIterator>::IntoIter;
    fn iter(&'a self) -> Self::IntoIter { self.into_iter() }
}

fn test(v: &'static impl BorrowIter<'static>) {
    println!("len = {}", v.iter().count());
}

fn main() {
    test(&[2, 3, 5]);
}

It is hard to get rid of this lifetime. Consider: what happens if &'static SomeContainer implements IntoIterator while &'other_lt SomeContainer does not?

You can add a where clause to the trait:

trait BasicStruct where for<'a> &'a Self: IntoIterator,

Playground.

Supertraits in general are just syntactic sugar for

trait BasicStruct where Self: Clone + ...
8 Likes

Thank you so much :heart_exclamation: i was banging my head at the compiler for too much time.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.