File tree 2 files changed +47
-1
lines changed
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> {
144
144
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
145
145
unsafe impl < #[ may_dangle] T > Drop for VecDeque < T > {
146
146
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
+
147
159
let ( front, back) = self . as_mut_slices ( ) ;
148
160
unsafe {
161
+ let _back_dropper = Dropper ( back) ;
149
162
// use drop for [T]
150
163
ptr:: drop_in_place ( front) ;
151
- ptr:: drop_in_place ( back) ;
152
164
}
153
165
// RawVec handles deallocation
154
166
}
Original file line number Diff line number Diff line change @@ -2,6 +2,7 @@ use std::collections::TryReserveError::*;
2
2
use std:: collections:: { vec_deque:: Drain , VecDeque } ;
3
3
use std:: fmt:: Debug ;
4
4
use std:: mem:: size_of;
5
+ use std:: panic:: catch_unwind;
5
6
use std:: { isize, usize} ;
6
7
7
8
use crate :: hash;
@@ -709,6 +710,39 @@ fn test_drop_clear() {
709
710
assert_eq ! ( unsafe { DROPS } , 4 ) ;
710
711
}
711
712
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
+
712
746
#[ test]
713
747
fn test_reserve_grow ( ) {
714
748
// test growth path A
You can’t perform that action at this time.
0 commit comments