Why is BufReader generic over <R> rather than <R: Read>?

I feel I won’t truly understand Rust until I understand the design decisions behind the standard library. So for my first question here:

Why is BufReader generic over rather than <R: Read>? As new() is only defined in an impl<R: Read> block there’s no way to create a BufReader over a type that doesn’t implement Read. Is it just to avoid BufReader having to specify Read again when implementing other traits (for example, with impl<R: Seek> rather than impl<R: Read + Seek>)? Or is there a benefit for users of BufReader?

It's generally considered good practice not to restrict generic parameters on type definitions unnecessarily. Generics should be restricted by bounds only if some implementation actually needs them, or when they otherwise convey semantics and/or required for correctness (in the case of purely marker traits).

I wrote about why not putting bounds on your type definitions is more flexible and idiomatic here.

7 Likes

Thank you; your example with the enum clearly shows the benefit of omitting the trait bound on the struct.