diff options
| author | Tyler Mandry <tmandry@gmail.com> | 2020-04-30 15:23:08 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-30 15:23:08 -0700 |
| commit | 4adebb9f29d862a0723ab982944a2909ea2fdcc1 (patch) | |
| tree | 861555cc7d3952840bfa2051175d4d63df73b034 /src/liballoc/vec.rs | |
| parent | 7ced01a730e8fc1bae2f8d4369c26812c0484da4 (diff) | |
| parent | f654daf3a6681e6d412db1e3203801353b9089c7 (diff) | |
| download | rust-4adebb9f29d862a0723ab982944a2909ea2fdcc1.tar.gz rust-4adebb9f29d862a0723ab982944a2909ea2fdcc1.zip | |
Rollup merge of #71148 - bluss:vec-drop-raw-slice, r=RalfJung
Vec drop and truncate: drop using raw slice *mut [T]
By creating a *mut [T] directly (without going through &mut [T]), avoid
questions of validity of the contents of the slice.
Consider the following risky code:
```rust
unsafe {
let mut v = Vec::<bool>::with_capacity(16);
v.set_len(16);
}
```
The intention is that with this change, we avoid one of the soundness
questions about the above snippet, because Vec::drop no longer
produces a mutable slice of the vector's contents.
r? @RalfJung
Diffstat (limited to 'src/liballoc/vec.rs')
| -rw-r--r-- | src/liballoc/vec.rs | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index b4a9da84787..cbfbf4d1cd3 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -741,7 +741,7 @@ impl<T> Vec<T> { return; } let remaining_len = self.len - len; - let s = slice::from_raw_parts_mut(self.as_mut_ptr().add(len), remaining_len); + let s = ptr::slice_from_raw_parts_mut(self.as_mut_ptr().add(len), remaining_len); self.len = len; ptr::drop_in_place(s); } @@ -2379,7 +2379,9 @@ unsafe impl<#[may_dangle] T> Drop for Vec<T> { fn drop(&mut self) { unsafe { // use drop for [T] - ptr::drop_in_place(&mut self[..]); + // use a raw slice to refer to the elements of the vector as weakest necessary type; + // could avoid questions of validity in certain cases + ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.as_mut_ptr(), self.len)) } // RawVec handles deallocation } @@ -2596,7 +2598,11 @@ impl<T> IntoIter<T> { /// ``` #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")] pub fn as_mut_slice(&mut self) -> &mut [T] { - unsafe { slice::from_raw_parts_mut(self.ptr as *mut T, self.len()) } + unsafe { &mut *self.as_raw_mut_slice() } + } + + fn as_raw_mut_slice(&mut self) -> *mut [T] { + ptr::slice_from_raw_parts_mut(self.ptr as *mut T, self.len()) } } @@ -2708,7 +2714,7 @@ unsafe impl<#[may_dangle] T> Drop for IntoIter<T> { let guard = DropGuard(self); // destroy the remaining elements unsafe { - ptr::drop_in_place(guard.0.as_mut_slice()); + ptr::drop_in_place(guard.0.as_raw_mut_slice()); } // now `guard` will be dropped and do the rest } |
