In your example, the two codes are strictly equivalent.
The where clauses were introduced to allow more expressive bound-checking, doing for example :
fn foo<T>(a: T) where Bar<T>: MyTrait { /* ... */ }
Which is not possible using only the old syntax.
Using where rather than the original syntax is generally preferred for readability even if the old syntax can still be used.
You can imagine for example constructions like
fn foo<A, B, C>(a: A, b: B, c: C)
where A: SomeTrait + OtherTrait,
B: ThirdTrait<A>+ OtherTrait,
C: LastTrait<A, B>
{
/* stuff here */
}
which are much more readable this way, even if the could still be expressed using the old syntax.
For your question about the CharEq trait, the code is:
impl<F> CharEq for F where F: FnMut(char) -> bool {
#[inline]
fn matches(&mut self, c: char) -> bool { (*self)(c) }
#[inline]
fn only_ascii(&self) -> bool { false }
}
It literally means: Implementation of trait CharEq for all type F that already implements the trait FnMut(char) -> bool (that is, a closure or a function taking a char and returning a bool).
For more details, you can look at the RFC that introduced the where clauses : https://github.com/rust-lang/rfcs/pull/135