Handle out of memory errors in io:Read::read_to_end()
#116570 got stuck due to a [procedural confusion](https://github.com/rust-lang/rust/pull/116570#issuecomment-1768271068). Retrying so that it can get FCP with the proper team now. cc `@joshtriplett` `@BurntSushi`
----
I'd like to propose handling of out-of-memory errors in the default implementation of `io::Read::read_to_end()` and `fs::read()`. These methods create/grow a `Vec` with a size that is external to the program, and could be arbitrarily large.
Due to being I/O methods, they can already fail in a variety of ways, in theory even including `ENOMEM` from the OS too, so another failure case should not surprise anyone.
While this may not help much Linux with overcommit, it's useful for other platforms like WASM. [Internals thread](https://internals.rust-lang.org/t/io-read-read-to-end-should-handle-oom/19662).
I've added documentation that makes it explicit that the OOM handling is a nice-to-have, and not a guarantee of the trait.
I haven't changed the implementation of `impl Read for &[u8]` and `VecDeque` out of caution, because in these cases users could assume `read` can't fail.
This code uses `try_reserve()` + `extend_from_slice()` which is optimized since #117503.