Skip to content

Commit 97d082c

Browse files
committed
Make vec::Drain and binary_heap::Drain covariant
1 parent 936bfea commit 97d082c

File tree

4 files changed

+40
-48
lines changed

4 files changed

+40
-48
lines changed

src/libcollections/binary_heap.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1016,12 +1016,12 @@ impl<T> ExactSizeIterator for IntoIter<T> {}
10161016

10171017
/// An iterator that drains a `BinaryHeap`.
10181018
#[stable(feature = "drain", since = "1.6.0")]
1019-
pub struct Drain<'a, T: 'a> {
1020-
iter: vec::Drain<'a, T>,
1019+
pub struct Drain<T> {
1020+
iter: vec::Drain<T>,
10211021
}
10221022

10231023
#[stable(feature = "rust1", since = "1.0.0")]
1024-
impl<'a, T: 'a> Iterator for Drain<'a, T> {
1024+
impl<T> Iterator for Drain<T> {
10251025
type Item = T;
10261026

10271027
#[inline]
@@ -1036,15 +1036,15 @@ impl<'a, T: 'a> Iterator for Drain<'a, T> {
10361036
}
10371037

10381038
#[stable(feature = "rust1", since = "1.0.0")]
1039-
impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
1039+
impl<T> DoubleEndedIterator for Drain<T> {
10401040
#[inline]
10411041
fn next_back(&mut self) -> Option<T> {
10421042
self.iter.next_back()
10431043
}
10441044
}
10451045

10461046
#[stable(feature = "rust1", since = "1.0.0")]
1047-
impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {}
1047+
impl<T> ExactSizeIterator for Drain<T> {}
10481048

10491049
#[stable(feature = "rust1", since = "1.0.0")]
10501050
impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {

src/libcollections/vec.rs

+23-43
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ use core::ops::{Index, IndexMut};
7474
use core::ops;
7575
use core::ptr;
7676
use core::slice;
77+
use super::vec_deque::VecDeque;
7778

7879
use super::SpecExtend;
7980
use super::range::RangeArgument;
@@ -843,20 +844,20 @@ impl<T> Vec<T> {
843844
let end = *range.end().unwrap_or(&len);
844845
assert!(start <= end);
845846
assert!(end <= len);
847+
let mut drain_vec = VecDeque::new();
846848

847849
unsafe {
848-
// set self.vec length's to start, to be safe in case Drain is leaked
849-
self.set_len(start);
850-
// Use the borrow in the IterMut to indicate borrowing behavior of the
851-
// whole Drain iterator (like &mut T).
852-
let range_slice = slice::from_raw_parts_mut(self.as_mut_ptr().offset(start as isize),
853-
end - start);
854-
Drain {
855-
tail_start: end,
856-
tail_len: len - end,
857-
iter: range_slice.iter_mut(),
858-
vec: self as *mut _,
850+
for i in start..end {
851+
let p = self.as_ptr().offset(i as isize);
852+
drain_vec.push_back(ptr::read(p));
859853
}
854+
let src = self.as_ptr().offset(end as isize);
855+
let dst = self.as_mut_ptr().offset(start as isize);
856+
ptr::copy(src, dst, len - end);
857+
self.set_len(len - (end - start));
858+
}
859+
Drain {
860+
deque: drain_vec
860861
}
861862
}
862863

@@ -1755,64 +1756,43 @@ impl<T> Drop for IntoIter<T> {
17551756
/// [`drain`]: struct.Vec.html#method.drain
17561757
/// [`Vec`]: struct.Vec.html
17571758
#[stable(feature = "drain", since = "1.6.0")]
1758-
pub struct Drain<'a, T: 'a> {
1759-
/// Index of tail to preserve
1760-
tail_start: usize,
1761-
/// Length of tail
1762-
tail_len: usize,
1759+
pub struct Drain<T> {
17631760
/// Current remaining range to remove
1764-
iter: slice::IterMut<'a, T>,
1765-
vec: *mut Vec<T>,
1761+
deque: VecDeque<T>
17661762
}
17671763

17681764
#[stable(feature = "drain", since = "1.6.0")]
1769-
unsafe impl<'a, T: Sync> Sync for Drain<'a, T> {}
1765+
unsafe impl<T: Sync> Sync for Drain<T> {}
17701766
#[stable(feature = "drain", since = "1.6.0")]
1771-
unsafe impl<'a, T: Send> Send for Drain<'a, T> {}
1767+
unsafe impl<T: Send> Send for Drain<T> {}
17721768

17731769
#[stable(feature = "rust1", since = "1.0.0")]
1774-
impl<'a, T> Iterator for Drain<'a, T> {
1770+
impl<T> Iterator for Drain<T> {
17751771
type Item = T;
17761772

17771773
#[inline]
17781774
fn next(&mut self) -> Option<T> {
1779-
self.iter.next().map(|elt| unsafe { ptr::read(elt as *const _) })
1775+
self.deque.pop_front()
17801776
}
17811777

17821778
fn size_hint(&self) -> (usize, Option<usize>) {
1783-
self.iter.size_hint()
1779+
(self.deque.len(), Some(self.deque.len()))
17841780
}
17851781
}
17861782

17871783
#[stable(feature = "rust1", since = "1.0.0")]
1788-
impl<'a, T> DoubleEndedIterator for Drain<'a, T> {
1784+
impl<T> DoubleEndedIterator for Drain<T> {
17891785
#[inline]
17901786
fn next_back(&mut self) -> Option<T> {
1791-
self.iter.next_back().map(|elt| unsafe { ptr::read(elt as *const _) })
1787+
self.deque.pop_back()
17921788
}
17931789
}
17941790

17951791
#[stable(feature = "rust1", since = "1.0.0")]
1796-
impl<'a, T> Drop for Drain<'a, T> {
1792+
impl<T> Drop for Drain<T> {
17971793
fn drop(&mut self) {
1798-
// exhaust self first
1799-
while let Some(_) = self.next() {}
1800-
1801-
if self.tail_len > 0 {
1802-
unsafe {
1803-
let source_vec = &mut *self.vec;
1804-
// memmove back untouched tail, update to new length
1805-
let start = source_vec.len();
1806-
let tail = self.tail_start;
1807-
let src = source_vec.as_ptr().offset(tail as isize);
1808-
let dst = source_vec.as_mut_ptr().offset(start as isize);
1809-
ptr::copy(src, dst, self.tail_len);
1810-
source_vec.set_len(start + self.tail_len);
1811-
}
1812-
}
18131794
}
18141795
}
18151796

1816-
18171797
#[stable(feature = "rust1", since = "1.0.0")]
1818-
impl<'a, T> ExactSizeIterator for Drain<'a, T> {}
1798+
impl<T> ExactSizeIterator for Drain<T> {}

src/libcollectionstest/binary_heap.rs

+6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
use std::collections::BinaryHeap;
12+
use std::collections::binary_heap::Drain;
1213

1314
#[test]
1415
fn test_iterator() {
@@ -292,3 +293,8 @@ fn test_extend_specialization() {
292293

293294
assert_eq!(a.into_sorted_vec(), [-20, -10, 1, 2, 3, 3, 5, 43]);
294295
}
296+
297+
#[allow(dead_code)]
298+
fn assert_covariance() {
299+
fn drain<'new>(d: Drain<&'static str>) -> Drain<&'new str> { d }
300+
}

src/libcollectionstest/vec.rs

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use std::borrow::Cow;
1212
use std::iter::{FromIterator, repeat};
1313
use std::mem::size_of;
14+
use std::vec::Drain;
1415

1516
use test::Bencher;
1617

@@ -510,6 +511,11 @@ fn test_cow_from() {
510511
}
511512
}
512513

514+
#[allow(dead_code)]
515+
fn assert_covariance() {
516+
fn drain<'new>(d: Drain<&'static str>) -> Drain<&'new str> { d }
517+
}
518+
513519
#[bench]
514520
fn bench_new(b: &mut Bencher) {
515521
b.iter(|| {

0 commit comments

Comments
 (0)