BTW: C++ resolves this via partial ordering (in overload resolution as well as selecting the right class template specialization). The more special template specialization wins. Example: Vec<int> is more special than Vec<T> for some type parameter T which is more special than U for some type parameter U.
What I like about this is that the C++ compiler “simply does the right thing” without me having to come up with constraints that are satisfied for exactly one impl (using negative predicates, for example). And I can later add a specialization without having to further restrict already existing specializations.
This would, for example, allow optimizing ToString for string slices simply by adding an impl of ToString for &'a str which is “more special” than an impl for T where T: Show.
But I guess these kinds of “overload resolution” rules can get pretty complicated. There are “patterns” like Vec<T> vs U and also different kinds of bounds involved where trait inheritance also induces a partial ordering. The book “C++ templates – The Complete Guide” dedicated a complete chapter for these kinds of overload resolution rules if I recall correctly and C++ doesn’t even have something like traits yet. 