This is caused by a performance hack we’d like to remove. The hack kicks in with operators only and not functions, skipping generic overload choices if a concrete overload matched.
In this case the generic overload (for integers) yields a better solution, because it does not involve a non-default literal type. However we don’t consider that overload at all, because the three float overloads matched first.
It’s because -0 and 0 have the same binary representation, so the former is still a valid value for an unsigned type.
I guess to be really consistent we’d also need to define a unary overload of - for unsigned values which traps if the value is non-zero, and otherwise returns zero, but that seems like a pointless footgun in practice.