You cannot apply the "{}", thing formatting on any thing, only on those whose type implements the Display trait:
use ::core::fmt::Display;
fn print_fail<T> (x: T)
{
println!("{}", x); // Error, x: T and we don't know if `T : Display`
}
fn print_ok<T> (x: T)
where
T : Display // Set up added bounds / constraints on the generics
{
println!("{}", x); // Ok, since `T : Display` we can display `x`
}
// or equivalently
fn print_ok<T : Display> (x: T)
{
println!("{}", x); // Ok, since `T : Display` we can display `x`
}
This is because when defining a function generic over, let's say, <T>, the caller may then feed any type T to that function, even types that are not Display, and in that case Rust would be unable to compile the "{}", x formatting line (operation would not be definedà
By adding the T : Display bound, callers are no longer allowed to use a type that would not implement that trait, thus effectively guaranteeing that any used type implements Display and that "{}", x will thus always be well-defined, no matter the type T (of x).
In your example, the mixup() function needs to have a
where
T : Display, // type of mixed.x
W : Display, // type of mixed.y
Thanks for your thorough explanation. I understand now!
Simply speaking, inside the mixup method, the println macro can't be certain that for each call the x and y implement the Display trait, but in main, for this specific p1 and p2 the compiler knows the result implement the Display trait so the compiler won't complain. Am I right?