Understanding of unconstrained type parameters

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?)

The type parameter I is unconstrained. You are only using it in the argument for the Fn trait bound. What if I implenent Fn(u32) and Fn(String) -> u8? This is possible in nightly.

When you put I in the generic parameter of the trait, you constrained I there.

1 Like