File tree Expand file tree Collapse file tree 2 files changed +47
-1
lines changed Expand file tree Collapse file tree 2 files changed +47
-1
lines changed Original file line number Diff line number Diff line change @@ -144,11 +144,23 @@ impl<T: Clone> Clone for VecDeque<T> {
144144#[ stable( feature = "rust1" , since = "1.0.0" ) ]
145145unsafe impl < #[ may_dangle] T > Drop for VecDeque < T > {
146146 fn drop ( & mut self ) {
147+ /// Runs the destructor for all items in the slice when it gets dropped (normally or
148+ /// during unwinding).
149+ struct Dropper < ' a , T > ( & ' a mut [ T ] ) ;
150+
151+ impl < ' a , T > Drop for Dropper < ' a , T > {
152+ fn drop ( & mut self ) {
153+ unsafe {
154+ ptr:: drop_in_place ( self . 0 ) ;
155+ }
156+ }
157+ }
158+
147159 let ( front, back) = self . as_mut_slices ( ) ;
148160 unsafe {
161+ let _back_dropper = Dropper ( back) ;
149162 // use drop for [T]
150163 ptr:: drop_in_place ( front) ;
151- ptr:: drop_in_place ( back) ;
152164 }
153165 // RawVec handles deallocation
154166 }
Original file line number Diff line number Diff line change @@ -2,6 +2,7 @@ use std::collections::TryReserveError::*;
22use std:: collections:: { vec_deque:: Drain , VecDeque } ;
33use std:: fmt:: Debug ;
44use std:: mem:: size_of;
5+ use std:: panic:: catch_unwind;
56use std:: { isize, usize} ;
67
78use crate :: hash;
@@ -709,6 +710,39 @@ fn test_drop_clear() {
709710 assert_eq ! ( unsafe { DROPS } , 4 ) ;
710711}
711712
713+ #[ test]
714+ fn test_drop_panic ( ) {
715+ static mut DROPS : i32 = 0 ;
716+
717+ struct D ( bool ) ;
718+
719+ impl Drop for D {
720+ fn drop ( & mut self ) {
721+ unsafe {
722+ DROPS += 1 ;
723+ }
724+
725+ if self . 0 {
726+ panic ! ( "panic in `drop`" ) ;
727+ }
728+ }
729+ }
730+
731+ let mut q = VecDeque :: new ( ) ;
732+ q. push_back ( D ( false ) ) ;
733+ q. push_back ( D ( false ) ) ;
734+ q. push_back ( D ( false ) ) ;
735+ q. push_back ( D ( false ) ) ;
736+ q. push_back ( D ( false ) ) ;
737+ q. push_front ( D ( false ) ) ;
738+ q. push_front ( D ( false ) ) ;
739+ q. push_front ( D ( true ) ) ;
740+
741+ catch_unwind ( move || drop ( q) ) . ok ( ) ;
742+
743+ assert_eq ! ( unsafe { DROPS } , 8 ) ;
744+ }
745+
712746#[ test]
713747fn test_reserve_grow ( ) {
714748 // test growth path A
You can’t perform that action at this time.
0 commit comments