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> {
856
856
/// ```
857
857
#[ stable( feature = "deque_extras" , since = "1.16.0" ) ]
858
858
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
+ }
861
884
}
862
885
}
863
886
You can’t perform that action at this time.
0 commit comments