'Equality constraints in trait in Rust. Variant with Into<T> trait

I want the ToKeyIter::Item be equal to ToKeyIter::KeyIter::Item as KeyIter should implement Iterator trait. I couldn't do it because with constraint equality in where clause. That's why I decided to use trait Into.

pub trait ToKeyIter {
    type Item: Clone + Hash + Eq;
    type KeyIter<'b>: Iterator where Self: 'b, <Self::KeyIter<'b> as Iterator>::Item: Into<Self::Item>;
    fn key_iter<'a> (&'a self) -> Self::KeyIter<'a> 
    where <Self::KeyIter<'a> as Iterator>::Item: Into<Self::Item>;
}

The trait itself compiles, but when I try to impl it for str or String, the compiler fails with "overflow evaluating the requirement".

impl ToKeyIter for str {
    type Item = char;
    type KeyIter<'a> = Chars<'a>;

    fn key_iter<'a> (&'a self) -> Chars<'a> {
        self.chars()
    }
}


impl ToKeyIter for String {
    type Item = char;
    type KeyIter<'a> = Chars<'a>;
    
    fn key_iter<'a> (&'a self) -> Chars<'a> {
        self.chars()
    }
} 

If you can tell how to write something like this

Key::Item == Key::KeyIter::Item

it will be great. But also I want to know what I should do to have correct impl for str and String with Into trait.



Solution 1:[1]

You can specify the Iterate<Item=Self::Item> to obtain what you want. See the playground for a live version of this:

#![feature(generic_associated_types)]

use std::hash::Hash;
use std::str::Chars;

pub trait ToKeyIter {
    type Item: Clone + Hash + Eq;
    type KeyIter<'a>: Iterator<Item=Self::Item>
    where
        Self: 'a;
    fn key_iter<'a>(&'a self) -> Self::KeyIter<'a>;
}

impl ToKeyIter for str {
    type Item = char;
    type KeyIter<'a> = Chars<'a>;

    fn key_iter<'a> (&'a self) -> Chars<'a> {
        self.chars()
    }
}
impl ToKeyIter for String {
    type Item = char;
    type KeyIter<'a> = Chars<'a>;
    
    fn key_iter<'a> (&'a self) -> Chars<'a> {
        self.chars()
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 BlackBeans