]> git.lizzy.rs Git - rust.git/commitdiff
VecDeque::drain: make sure the 'drain' raw pointer is actually still usable
authorRalf Jung <post@ralfj.de>
Thu, 22 Nov 2018 07:57:26 +0000 (08:57 +0100)
committerRalf Jung <post@ralfj.de>
Fri, 7 Dec 2018 08:20:54 +0000 (09:20 +0100)
src/liballoc/collections/vec_deque.rs

index c8ee40f3d2735365560e037fc88977d847cbf305..60b5d8063bff2d2cbba558c4749584702f20ba8d 100644 (file)
@@ -1019,14 +1019,19 @@ pub fn drain<R>(&mut self, range: R) -> Drain<T>
         // the drain is complete and the Drain destructor is run.
         self.head = drain_tail;
 
+        // `deque` and `ring` overlap in what they point to, so we must make sure
+        // that `ring` is "derived-from" `deque`, or else even just creating ring
+        // from `self` already invalidates `deque`.
+        let deque = NonNull::from(&mut *self);
+
         Drain {
-            deque: NonNull::from(&mut *self),
+            deque,
             after_tail: drain_head,
             after_head: head,
             iter: Iter {
                 tail: drain_tail,
                 head: drain_head,
-                ring: unsafe { self.buffer_as_mut_slice() },
+                ring: unsafe { (&mut *deque.as_ptr()).buffer_as_mut_slice() },
             },
         }
     }