mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Rollup merge of #92097 - saethlin:split-without-deref, r=the8472
Implement split_at_spare_mut without Deref to a slice so that the spare slice is valid ~I'm not sure I understand what's going on here correctly. And I'm pretty sure this safety comment needs to be changed. I'm just referring to the same thing that `as_mut_ptr_range` does.~ (Thanks `@RalfJung` for the guidance and clearing things up) I tried to run https://github.com/rust-lang/miri-test-libstd on alloc with -Zmiri-track-raw-pointers, and got a failure on the test `vec::test_extend_from_within`. I minimized the test failure into this program: ```rust #![feature(vec_split_at_spare)] fn main() { Vec::<i32>::with_capacity(1).split_at_spare_mut(); } ``` The problem is that the existing implementation is actually getting a pointer range where both pointers are derived from the initialized region of the Vec's allocation, but we need the second one to be valid for the region between len and capacity. (thanks Ralf for clearing this up)
This commit is contained in:
commit
a6e4d684aa
@ -2141,12 +2141,17 @@ impl<T, A: Allocator> Vec<T, A> {
|
||||
unsafe fn split_at_spare_mut_with_len(
|
||||
&mut self,
|
||||
) -> (&mut [T], &mut [MaybeUninit<T>], &mut usize) {
|
||||
let Range { start: ptr, end: spare_ptr } = self.as_mut_ptr_range();
|
||||
let ptr = self.as_mut_ptr();
|
||||
// SAFETY:
|
||||
// - `ptr` is guaranteed to be valid for `self.len` elements
|
||||
// - but the allocation extends out to `self.buf.capacity()` elements, possibly
|
||||
// uninitialized
|
||||
let spare_ptr = unsafe { ptr.add(self.len) };
|
||||
let spare_ptr = spare_ptr.cast::<MaybeUninit<T>>();
|
||||
let spare_len = self.buf.capacity() - self.len;
|
||||
|
||||
// SAFETY:
|
||||
// - `ptr` is guaranteed to be valid for `len` elements
|
||||
// - `ptr` is guaranteed to be valid for `self.len` elements
|
||||
// - `spare_ptr` is pointing one element past the buffer, so it doesn't overlap with `initialized`
|
||||
unsafe {
|
||||
let initialized = slice::from_raw_parts_mut(ptr, self.len);
|
||||
|
Loading…
Reference in New Issue
Block a user