fix aliasing in drain_range

This commit is contained in:
Ralf Jung
2019-11-16 09:47:40 +01:00
parent fc6664c540
commit 9beb753473
+6 -3
View File
@@ -600,12 +600,15 @@ impl<A: Array> ArrayVec<A> {
fn drain_range(&mut self, start: usize, end: usize) -> Drain<A> fn drain_range(&mut self, start: usize, end: usize) -> Drain<A>
{ {
let len = self.len(); let len = self.len();
// bounds check happens here
// bounds check happens here (before length is changed!)
let range_slice: *const _ = &self[start..end]; let range_slice: *const _ = &self[start..end];
// Calling `set_len` creates a fresh and thus unique mutable references, making all
// older aliases we created invalid. So we cannot call that function.
self.len = Index::from(start);
unsafe { unsafe {
// set self.vec length's to start, to be safe in case Drain is leaked
self.set_len(start);
Drain { Drain {
tail_start: end, tail_start: end,
tail_len: len - end, tail_len: len - end,