diff options
| author | Ralf Jung <post@ralfj.de> | 2018-11-22 08:57:26 +0100 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2018-12-07 09:20:54 +0100 |
| commit | b0c4a35a969aa94f6667cb885eebb184ee318a6d (patch) | |
| tree | 334ed475944efee0e9a104dbcc21e42ae8713d76 | |
| parent | 21b5950cf92a978f88dd65f408382637b60c52b5 (diff) | |
| download | rust-b0c4a35a969aa94f6667cb885eebb184ee318a6d.tar.gz rust-b0c4a35a969aa94f6667cb885eebb184ee318a6d.zip | |
VecDeque::drain: make sure the 'drain' raw pointer is actually still usable
| -rw-r--r-- | src/liballoc/collections/vec_deque.rs | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index c8ee40f3d27..60b5d8063bf 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -1019,14 +1019,19 @@ 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: 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() }, }, } } |
