about summary refs log tree commit diff
path: root/src/liballoc/collections
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2018-11-22 16:03:24 +0100
committerRalf Jung <post@ralfj.de>2018-12-07 09:20:54 +0100
commitfeb775c834361f635df9e3824f9d2ae9582becbb (patch)
tree70b369f048129684bc66188bf4d16d33929772b5 /src/liballoc/collections
parentb0c4a35a969aa94f6667cb885eebb184ee318a6d (diff)
downloadrust-feb775c834361f635df9e3824f9d2ae9582becbb.tar.gz
rust-feb775c834361f635df9e3824f9d2ae9582becbb.zip
Drain only needs a shared reference
Diffstat (limited to 'src/liballoc/collections')
-rw-r--r--src/liballoc/collections/vec_deque.rs12
1 files changed, 5 insertions, 7 deletions
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index 60b5d8063bf..4a3604f202f 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -1019,19 +1019,17 @@ impl<T> VecDeque<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,
+            deque: NonNull::from(&mut *self),
             after_tail: drain_head,
             after_head: head,
             iter: Iter {
                 tail: drain_tail,
                 head: drain_head,
-                ring: unsafe { (&mut *deque.as_ptr()).buffer_as_mut_slice() },
+                // Crucially, we only create shared references from `self` here and read from
+                // it.  We do not write to `self` nor reborrow to a mutable reference.
+                // Hence the raw pointer we created above, for `deque`, remains valid.
+                ring: unsafe { self.buffer_as_slice() },
             },
         }
     }