@@ -73,8 +73,8 @@ use core::mem;
7373use core:: ops:: { Index , IndexMut } ;
7474use core:: ops;
7575use core:: ptr;
76+ use core:: ptr:: Shared ;
7677use core:: slice;
77- use super :: vec_deque:: VecDeque ;
7878
7979use super :: SpecExtend ;
8080use super :: range:: RangeArgument ;
@@ -844,20 +844,20 @@ impl<T> Vec<T> {
844844 let end = * range. end ( ) . unwrap_or ( & len) ;
845845 assert ! ( start <= end) ;
846846 assert ! ( end <= len) ;
847- let mut drain_vec = VecDeque :: new ( ) ;
848847
849848 unsafe {
850- for i in start..end {
851- let p = self . as_ptr ( ) . offset ( i as isize ) ;
852- drain_vec. push_back ( ptr:: read ( p) ) ;
849+ // set self.vec length's to start, to be safe in case Drain is leaked
850+ self . set_len ( start) ;
851+ // Use the borrow in the IterMut to indicate borrowing behavior of the
852+ // whole Drain iterator (like &mut T).
853+ let range_slice = slice:: from_raw_parts_mut ( self . as_mut_ptr ( ) . offset ( start as isize ) ,
854+ end - start) ;
855+ Drain {
856+ tail_start : end,
857+ tail_len : len - end,
858+ iter : range_slice. iter ( ) ,
859+ vec : Shared :: new ( self as * mut _ ) ,
853860 }
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
861861 }
862862 }
863863
@@ -1756,43 +1756,64 @@ impl<T> Drop for IntoIter<T> {
17561756/// [`drain`]: struct.Vec.html#method.drain
17571757/// [`Vec`]: struct.Vec.html
17581758#[ stable( feature = "drain" , since = "1.6.0" ) ]
1759- pub struct Drain < T > {
1759+ pub struct Drain < ' a , T : ' a > {
1760+ /// Index of tail to preserve
1761+ tail_start : usize ,
1762+ /// Length of tail
1763+ tail_len : usize ,
17601764 /// Current remaining range to remove
1761- deque : VecDeque < T >
1765+ iter : slice:: Iter < ' a , T > ,
1766+ vec : Shared < Vec < T > > ,
17621767}
17631768
17641769#[ stable( feature = "drain" , since = "1.6.0" ) ]
1765- unsafe impl < T : Sync > Sync for Drain < T > { }
1770+ unsafe impl < ' a , T : Sync > Sync for Drain < ' a , T > { }
17661771#[ stable( feature = "drain" , since = "1.6.0" ) ]
1767- unsafe impl < T : Send > Send for Drain < T > { }
1772+ unsafe impl < ' a , T : Send > Send for Drain < ' a , T > { }
17681773
17691774#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1770- impl < T > Iterator for Drain < T > {
1775+ impl < ' a , T > Iterator for Drain < ' a , T > {
17711776 type Item = T ;
17721777
17731778 #[ inline]
17741779 fn next ( & mut self ) -> Option < T > {
1775- self . deque . pop_front ( )
1780+ self . iter . next ( ) . map ( |elt| unsafe { ptr :: read ( elt as * const _ ) } )
17761781 }
17771782
17781783 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1779- ( self . deque . len ( ) , Some ( self . deque . len ( ) ) )
1784+ self . iter . size_hint ( )
17801785 }
17811786}
17821787
17831788#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1784- impl < T > DoubleEndedIterator for Drain < T > {
1789+ impl < ' a , T > DoubleEndedIterator for Drain < ' a , T > {
17851790 #[ inline]
17861791 fn next_back ( & mut self ) -> Option < T > {
1787- self . deque . pop_back ( )
1792+ self . iter . next_back ( ) . map ( |elt| unsafe { ptr :: read ( elt as * const _ ) } )
17881793 }
17891794}
17901795
17911796#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1792- impl < T > Drop for Drain < T > {
1797+ impl < ' a , T > Drop for Drain < ' a , T > {
17931798 fn drop ( & mut self ) {
1799+ // exhaust self first
1800+ while let Some ( _) = self . next ( ) { }
1801+
1802+ if self . tail_len > 0 {
1803+ unsafe {
1804+ let source_vec = & mut * * self . vec ;
1805+ // memmove back untouched tail, update to new length
1806+ let start = source_vec. len ( ) ;
1807+ let tail = self . tail_start ;
1808+ let src = source_vec. as_ptr ( ) . offset ( tail as isize ) ;
1809+ let dst = source_vec. as_mut_ptr ( ) . offset ( start as isize ) ;
1810+ ptr:: copy ( src, dst, self . tail_len ) ;
1811+ source_vec. set_len ( start + self . tail_len ) ;
1812+ }
1813+ }
17941814 }
17951815}
17961816
1817+
17971818#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1798- impl < T > ExactSizeIterator for Drain < T > { }
1819+ impl < ' a , T > ExactSizeIterator for Drain < ' a , T > { }
0 commit comments