Patterns cannot refer to runtime values. That's a consistent restriction. Guard clauses are for that. Something like x => foo(x) is always a catch-all pattern that introduces a new binding x rather than referring to some existing x. Except when x is an in-scope const or an enum variant. A range pattern like ..x is a sort of special case because it does not introduce a new binding and always expects x to be a constant.
Not sure what about it is "cruft"? I just took your match function and made the comparison explicit. It did go up from 5 lines to 6 if that is what you mean.
error[E0029]: only `char` and numeric types are allowed in range patterns
--> src/main.rs:3:11
|
3 | ..y => smaller,
| ^ this is of type `T` but it should be `char` or numeric
That looks like a bug. You should report that as an issue on rust-lang/rust, labeled as a diagnostic issue, and mention that the error was misleading and you'd expect to instead get something telling you that you can't use a runtime value in a pattern match.