Skip to content

Commit a6e4d68

Browse files
authored
Rollup merge of rust-lang#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)
2 parents 5a5c928 + 777c853 commit a6e4d68

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

library/alloc/src/vec/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2141,12 +2141,17 @@ impl<T, A: Allocator> Vec<T, A> {
21412141
unsafe fn split_at_spare_mut_with_len(
21422142
&mut self,
21432143
) -> (&mut [T], &mut [MaybeUninit<T>], &mut usize) {
2144-
let Range { start: ptr, end: spare_ptr } = self.as_mut_ptr_range();
2144+
let ptr = self.as_mut_ptr();
2145+
// SAFETY:
2146+
// - `ptr` is guaranteed to be valid for `self.len` elements
2147+
// - but the allocation extends out to `self.buf.capacity()` elements, possibly
2148+
// uninitialized
2149+
let spare_ptr = unsafe { ptr.add(self.len) };
21452150
let spare_ptr = spare_ptr.cast::<MaybeUninit<T>>();
21462151
let spare_len = self.buf.capacity() - self.len;
21472152

21482153
// SAFETY:
2149-
// - `ptr` is guaranteed to be valid for `len` elements
2154+
// - `ptr` is guaranteed to be valid for `self.len` elements
21502155
// - `spare_ptr` is pointing one element past the buffer, so it doesn't overlap with `initialized`
21512156
unsafe {
21522157
let initialized = slice::from_raw_parts_mut(ptr, self.len);

0 commit comments

Comments
 (0)