Reputation: 6848
I want to write a function tokenize
that takes char
s from an iterator. Like this:
fn tokenize<F: IntoIterator<Item=char>>(file: F)
If I want to use a &str
with this function, I can do it like this:
tokenize("foo".chars())
That works OK.
Now, I'd like to avoid that .chars()
specifically for type &str
, since I know that, if I'm given a &str
, I can make it what I want by calling .chars()
.
I tried declaring a new trait, IntoChars
, and implement it for &str
:
trait IntoChars {
type T: Iterator<Item=char>;
fn into_chars(&self) -> Self::T;
}
impl<'a> IntoChars for &'a str {
type T = Chars<'a>;
fn into_chars(&self) -> Self::T {
self.chars()
}
}
If then I make my function like this:
tokenize<F: IntoChars>(file: F)
it works. Nice! But I want to implement IntoChars
also for any type that can give me chars, ie. is IntoIterator<Item=char>
.
impl<T: IntoIterator<Item=char>> IntoChars for T {
type T = T::IntoIter;
fn into_chars(self) -> Self::T {
self.into_iter()
}
}
That doesn't work. For two reasons:
IntoIter::into_iter
takes a self
, but IntoChars::into_chars
takes a &self
. This is specifically because I don't want to consume &str
when calling its into_chars
method unnecessarily. Is there any way to achieve both?IntoChars::into_chars
take a self
. This still doesn't work; I get: error: conflicting implementations for trait `IntoChars` [E0119]
. But if I remove the impl<'a> IntoChars for &'a str
, I get error: the trait `core::iter::Iterator` is not implemented for the type `&str`
. Why is is conflicting then?Any way I can achieve this?
Upvotes: 1
Views: 142
Reputation: 432059
Let's look at your two implementations, which I've rewritten in the more verbose form:
impl<T> IntoChars for T
where T: IntoIterator<Item = char>
impl<'a> IntoChars for &'a str
What should the compiler do when whoever owns either the trait IntoIterator
or the type &str
decides to implement IntoIterator
for &str
? All of the sudden, you'd have conflicting implementations for the same trait; There are two ways that IntoChars
would be implemented for &str
.
Other keywords for this problem are trait coherence and orphan rules.
To be able to compile this, you'd need impl specialization, which is an RFC that has not been accepted yet.
Upvotes: 2