@@ -417,24 +417,23 @@ impl<T, A: Allocator> VecDeque<T, A> {
417
417
}
418
418
}
419
419
420
- /// Append all values from `src` to `self `, wrapping around if needed.
420
+ /// Append all values from `src` to `dst `, wrapping around if needed.
421
421
/// Assumes capacity is sufficient.
422
422
#[ inline]
423
- unsafe fn append_slice ( & mut self , src : & [ T ] ) {
424
- debug_assert ! ( self . len ( ) + src. len( ) + 1 <= self . cap( ) ) ;
425
- let head_room = self . cap ( ) - self . head ;
426
- if self . head < self . tail || src. len ( ) <= head_room {
423
+ unsafe fn copy_slice ( & mut self , dst : usize , src : & [ T ] ) {
424
+ debug_assert ! ( src. len( ) <= self . cap( ) ) ;
425
+ let head_room = self . cap ( ) - dst ;
426
+ if src. len ( ) <= head_room {
427
427
unsafe {
428
- ptr:: copy_nonoverlapping ( src. as_ptr ( ) , self . ptr ( ) . add ( self . head ) , src. len ( ) ) ;
428
+ ptr:: copy_nonoverlapping ( src. as_ptr ( ) , self . ptr ( ) . add ( dst ) , src. len ( ) ) ;
429
429
}
430
430
} else {
431
431
let ( left, right) = src. split_at ( head_room) ;
432
432
unsafe {
433
- ptr:: copy_nonoverlapping ( left. as_ptr ( ) , self . ptr ( ) . add ( self . head ) , left. len ( ) ) ;
433
+ ptr:: copy_nonoverlapping ( left. as_ptr ( ) , self . ptr ( ) . add ( dst ) , left. len ( ) ) ;
434
434
ptr:: copy_nonoverlapping ( right. as_ptr ( ) , self . ptr ( ) , right. len ( ) ) ;
435
435
}
436
436
}
437
- self . head = self . wrap_add ( self . head , src. len ( ) ) ;
438
437
}
439
438
440
439
/// Frobs the head and tail sections around to handle the fact that we
@@ -2111,9 +2110,12 @@ impl<T, A: Allocator> VecDeque<T, A> {
2111
2110
self . reserve ( other. len ( ) ) ;
2112
2111
unsafe {
2113
2112
let ( left, right) = other. as_slices ( ) ;
2114
- self . append_slice ( left) ;
2115
- self . append_slice ( right) ;
2113
+ self . copy_slice ( self . head , left) ;
2114
+ self . copy_slice ( self . wrap_add ( self . head , left . len ( ) ) , right) ;
2116
2115
}
2116
+ // SAFETY: Update pointers after copying to avoid leaving doppelganger
2117
+ // in case of panics.
2118
+ self . head = self . wrap_add ( self . head , other. len ( ) ) ;
2117
2119
// Silently drop values in `other`.
2118
2120
other. tail = other. head ;
2119
2121
}
0 commit comments