File tree Expand file tree Collapse file tree 1 file changed +25
-2
lines changed Expand file tree Collapse file tree 1 file changed +25
-2
lines changed Original file line number Diff line number Diff line change @@ -856,8 +856,31 @@ impl<T> VecDeque<T> {
856856 /// ```
857857 #[ stable( feature = "deque_extras" , since = "1.16.0" ) ]
858858 pub fn truncate ( & mut self , len : usize ) {
859- for _ in len..self . len ( ) {
860- self . pop_back ( ) ;
859+ // Safe because:
860+ //
861+ // * Any slice passed to `drop_in_place` is valid; the second case has
862+ // `len <= front.len()` and returning on `len > self.len()` ensures
863+ // `begin <= back.len()` in the first case
864+ // * The head of the VecDeque is moved before calling `drop_in_place`,
865+ // so no value is dropped twice if `drop_in_place` panics
866+ unsafe {
867+ if len > self . len ( ) {
868+ return ;
869+ }
870+ let num_dropped = self . len ( ) - len;
871+ let ( front, back) = self . as_mut_slices ( ) ;
872+ if len > front. len ( ) {
873+ let begin = len - front. len ( ) ;
874+ let drop_back = back. get_unchecked_mut ( begin..) as * mut _ ;
875+ self . head = self . wrap_sub ( self . head , num_dropped) ;
876+ ptr:: drop_in_place ( drop_back) ;
877+ } else {
878+ let drop_back = back as * mut _ ;
879+ let drop_front = front. get_unchecked_mut ( len..) as * mut _ ;
880+ self . head = self . wrap_sub ( self . head , num_dropped) ;
881+ ptr:: drop_in_place ( drop_front) ;
882+ ptr:: drop_in_place ( drop_back) ;
883+ }
861884 }
862885 }
863886
You can’t perform that action at this time.
0 commit comments