I had a trait:
pub trait ReadToken<'t> {
type Token;
fn read_token(&self, text: &'t str) -> Self::Token;
}
I changed it to expand its capabilities:
pub trait ReadToken<'t> {
type Token;
type Info: ReadTokenInfo<'t>;
fn read_token(&self, info: Self::Info) -> Self::Token;
}
But when I want to write an implementation for a function (which was in the previous version)
impl<'t, T, F, I> ReadToken<'t> for F where
T: ReadToken<'t>,
F: Fn(I) -> T,
I: ReadTokenInfo<'t> {
type Token = T;
type Info = I;
fn read_token(&self, info: I) -> Self::Token {
self(info)
}
}
I get errors:
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
--> src\read_token.rs:27:10
|
27 | impl<'t, T, F, I> ReadToken<'t> for F where
| ^ unconstrained type parameter
error[E0207]: the type parameter `I` is not constrained by the impl trait, self type, or predicates
--> src\read_token.rs:27:16
|
27 | impl<'t, T, F, I> ReadToken<'t> for F where
| ^ unconstrained type parameter
error: aborting due to 2 previous errors
Ok. But what if I write something like:
pub trait ReadToken<'t, I = &'t str> where // It even maintains backward compatibility
I: ReadTokenInfo<'t> {
type Token;
fn read_token(&self, info: I) -> Self::Token;
}
impl<'t, T, F, I> ReadToken<'t, I> for F where
T: ReadToken<'t>,
F: Fn(I) -> T,
I: ReadTokenInfo<'t> {
type Token = T;
fn read_token(&self, info: I) -> Self::Token {
self(info)
}
}
And it compiles and passes all the tests!
But how does it work? What is the difference between this code? Is it really only in the default type?
Why can't I write like the first version? (or can?)