VecDeque: fix for stacked borrows
`VecDeque` violates a version of stacked borrows where creating a shared reference is not enough to make a location *mutably accessible* from raw pointers (and I think that is the version we want). There are two problems:
* Creating a `NonNull<T>` from `&mut T` goes through `&T` (inferred for a `_`), then `*const T`, then `NonNull<T>`. That means in this stricter version of Stacked Borrows, we cannot actually write to such a `NonNull` because it was created from a shared reference! This PR fixes that by going from `&mut T` to `*mut T` to `*const T`.
* `VecDeque::drain` creates the `Drain` struct by *first* creating a `NonNull` from `self` (which is an `&mut VecDeque`), and *then* calling `self.buffer_as_mut_slice()`. The latter reborrows `self`, asserting that `self` is currently the unique pointer to access this `VecDeque`, and hence invalidating the `NonNull` that was created earlier. This PR fixes that by instead using `self.buffer_as_slice()`, which only performs read accesses and creates only shared references, meaning the raw pointer (`NonNull`) remains valid.
It is possible that other methods on `VecDeque` do something similar, miri's test coverage of `VecDeque` is sparse to say the least.
Cc @nikomatsakis @Gankro
Introduce ptr::hash for references
The RHS is what I used, which wasn't as convenient as `ptr::eq`, so I wondered: should `ptr::hash` exist?
My first Rust PR, so I'm going to need some guidance. :)
drop glue takes in mutable references, it should reflect that in its type
When drop glue begins, it should retag, like all functions taking references do. But to do that, it needs to take the reference at a proper type: `&mut T`, not `*mut T`.
Failing to retag can mean that the memory the reference points to remains frozen, and `EscapeToRaw` on a frozen location is a NOP, meaning later mutations cause a Stacked Borrows violation.
Cc @nikomatsakis @Gankro because Stacked Borrows
Cc @eddyb for the changes to miri argument passing (the intention is to allow passing `*mut [u8]` when `&mut [u8]` is expected and vice versa)
Rename `CoerceSized` to `DispatchFromDyn`, and reverse the direction so that, for example, you write
```
impl<T: Unsize<U>, U> DispatchFromDyn<*const U> for *const T {}
```
instead of
```
impl<T: Unsize<U>, U> DispatchFromDyn<*const T> for *const U {}
```
this way the trait is really just a subset of `CoerceUnsized`.
The checks in object_safety.rs are updated for the new trait, and some documentation and method names in there are updated for the new trait name — e.g. `receiver_is_coercible` is now called `receiver_is_dispatchable`. Since the trait now works in the opposite direction, some code had to updated here for that too.
I did not update the error messages for invalid `CoerceSized` (now `DispatchFromDyn`) implementations, except to find/replace `CoerceSized` with `DispatchFromDyn`. Will ask for suggestions in the PR thread.
During review of the previous commit, @joshtriplett noticed that
the emphasis on 'the same' is unnecessary. For consistency, remove it
on the offset() functions, as well.
Ralf Jung made the same changes to the offset functions' documentation
in commit fb089156. As add/sub just call offset, the same limitation
applies here, as well.
Removed emphasis on review request by @joshtriplett
Rewrite docs for pointer methods
This takes over https://github.com/rust-lang/rust/pull/51016 by @ecstatic-morse. They did most of the work, I just did some editing.
However, I realized one problem: This updates the docs for the "free functions" in `core::ptr`, but it does not update the copies of these docs for the inherent methods of the `*const T` and `*mut T` types. These getting out-of-sync is certainly bad, but I also don't feel like copying all this stuff around. Instead, we should remove this redundancy. Any good ideas?