There are many cases where this sort of thing would be useful, not just this edge case. For instance, automatically rewriting between a recursive function and a function with an explicit external stack. Or swapping between an eagerly evaluated function and a lazily evaluated one. Or swapping between different types of allocations (stack, heap, region + bump pointer, etc). Or swapping between different ways of parallelizing a function or loop. Or swapping between row or column based evaluation. Or specifying two equivalent functions and have the compiler check as much as possible that they are equivilant, calling both and asserting on debug builds and calling the faster one on release builds (or potentially even calling
both in separate threads and waiting until either one returns). Etc.
All of these are things that you can do manually, and that you can leave to the compiler and hope that it'll pick the correct one, but currently good luck telling the compiler that no, you really actually want to do <x>. Or to try <x> and <y> and see which is better. And the amount of time required to do so manually adds up, even though they are all things that could be done by a compiler.
I personally wish that you could specify / annotate the range that you are actually intending to store in an integer (and have it optionally bound-checked) anyway, but that is another matter.
(Actually, I wish that you could specify types with an arbitrary (probably-pure) boolean function to indicate if something is or isn't a valid value in the type. But that is another matter indeed.)