This move a branch and more code into the cold method `finish_grow`,
which means that less code is inlined at each `try_reserve` site.
Additionally, this reduces the amount of parameters, so they can all be
passed by registers.
RawVecInner: add missing `unsafe` to unsafe fns
Some (module-private) functions in `library/alloc/src/raw_vec/mod.rs` are unsafe (i.e. may cause UB when called from safe code) but are not marked `unsafe`. Specifically:
- `RawVecInner::grow_exact` causes UB if called with `len` and `additional` arguments such that `len + additional` is less than the current capacity. Indeed, in that case it calls [Allocator::grow](https://doc.rust-lang.org/std/alloc/trait.Allocator.html#method.grow) with a `new_layout` that is smaller than `old_layout`, which violates a safety precondition.
- The RawVecInner methods for resizing the buffer cause UB if called with an `elem_layout` different from the one used to initially allocate the buffer, because in that case `Allocator::grow` or `Allocator::shrink` are called with an `old_layout` that does not *fit* the allocated block, which violates a safety precondition.
- `RawVecInner::current_memory` might cause UB if called with an `elem_layout` different from the one used to initially allocate the buffer, because the `unchecked_mul` might overflow.
- Furthermore, these methods cause UB if called with an `elem_layout` where the size is not a multiple of the alignment. This is because `Layout::repeat` is used (in `layout_array`) to compute the allocation's layout when allocating, which includes padding to ensure alignment of array elements, but simple multiplication is used (in `current_memory`) to compute the old allocation's layout when resizing or deallocating, which would cause the layout used to resize or deallocate to not *fit* the allocated block, which violates a safety precondition.
I discovered these issues while performing formal verification of `library/alloc/src/raw_vec/mod.rs` per [Challenge 19](https://model-checking.github.io/verify-rust-std/challenges/0019-rawvec.html) of the [AWS Rust Standard Library Verification Contest](https://aws.amazon.com/blogs/opensource/verify-the-safety-of-the-rust-standard-library/).
- RawVecInner::grow_exact causes UB if called with len and additional
arguments such that len + additional is less than the current
capacity. Indeed, in that case it calls Allocator::grow with a
new_layout that is smaller than old_layout, which violates a safety
precondition.
- All RawVecInner methods for resizing the buffer cause UB
if called with an elem_layout different from the one used to initially
allocate the buffer, because in that case Allocator::grow/shrink is called with
an old_layout that does not fit the allocated block, which violates a
safety precondition.
- RawVecInner::current_memory might cause UB if called with an elem_layout
different from the one used to initially allocate the buffer, because
the unchecked_mul might overflow.
- Furthermore, these methods cause UB if called with an elem_layout
where the size is not a multiple of the alignment. This is because
Layout::repeat is used (in layout_array) to compute the allocation's
layout when allocating, which includes padding to ensure alignment of
array elements, but simple multiplication is used (in current_memory) to
compute the old allocation's layout when resizing or deallocating, which
would cause the layout used to resize or deallocate to not fit the
allocated block, which violates a safety precondition.
raw_vec.rs: Remove superfluous fn alloc_guard
`alloc_guard` checks that its argument is at most `isize::MAX`, but it is called only with layout sizes, which are already guaranteed to be at most `isize::MAX`.
Use `std::mem::{size_of, size_of_val, align_of, align_of_val}` from the
prelude instead of importing or qualifying them.
These functions were added to all preludes in Rust 1.80.