A concrete type is a specific Rust type, such as i32, String, or a named type. Unlike a generic type parameter, it names one definite type. Without angle brackets such as <T>, Rust treats a type name as concrete and looks for that exact type. section 5.1
Concrete and generic function inputs
The function `return_item(item: i32) -> i32` accepts only i32. Replacing the fixed type with `return_item<T>(item: T) -> T` makes the function generic, so T can represent the caller’s type. Writing `return_item(item: MyType)` instead makes Rust search for one concrete type named MyType; adding `<MyType>` declares MyType as a type parameter. section 5.1
Closures make the distinction especially clear. Every closure has its own unique concrete type, even when two closures have identical signatures. The closures implement the Fn trait, but Fn describes their behavior rather than serving as their concrete type. A function taking two parameters of one generic type therefore rejects two separately written closures; using different parameters, F and G, accepts them. section 12.1.3


