@@ -126,6 +126,80 @@ fn test_drop() {
126126 }
127127}
128128
129+ #[ test]
130+ fn test_drop_panics ( ) {
131+ use std:: cell:: Cell ;
132+ use std:: panic:: catch_unwind;
133+ use std:: panic:: AssertUnwindSafe ;
134+
135+ let flag = & Cell :: new ( 0 ) ;
136+
137+ struct Bump < ' a > ( & ' a Cell < i32 > ) ;
138+
139+ // Panic in the first drop
140+ impl < ' a > Drop for Bump < ' a > {
141+ fn drop ( & mut self ) {
142+ let n = self . 0 . get ( ) ;
143+ self . 0 . set ( n + 1 ) ;
144+ if n == 0 {
145+ panic ! ( "Panic in Bump's drop" ) ;
146+ }
147+ }
148+ }
149+ // check if rust is new enough
150+ flag. set ( 0 ) ;
151+ {
152+ let array = vec ! [ Bump ( flag) , Bump ( flag) ] ;
153+ let res = catch_unwind ( AssertUnwindSafe ( || {
154+ drop ( array) ;
155+ } ) ) ;
156+ assert ! ( res. is_err( ) ) ;
157+ }
158+
159+ if flag. get ( ) != 2 {
160+ println ! ( "test_drop_panics: skip, this version of Rust doesn't continue in drop_in_place" ) ;
161+ return ;
162+ }
163+
164+ flag. set ( 0 ) ;
165+ {
166+ let mut array = ArrayVec :: < [ Bump ; 128 ] > :: new ( ) ;
167+ array. push ( Bump ( flag) ) ;
168+ array. push ( Bump ( flag) ) ;
169+ array. push ( Bump ( flag) ) ;
170+
171+ let res = catch_unwind ( AssertUnwindSafe ( || {
172+ drop ( array) ;
173+ } ) ) ;
174+ assert ! ( res. is_err( ) ) ;
175+ }
176+ // Check that all the elements drop, even if the first drop panics.
177+ assert_eq ! ( flag. get( ) , 3 ) ;
178+
179+
180+ flag. set ( 0 ) ;
181+ {
182+ let mut array = ArrayVec :: < [ Bump ; 16 ] > :: new ( ) ;
183+ array. push ( Bump ( flag) ) ;
184+ array. push ( Bump ( flag) ) ;
185+ array. push ( Bump ( flag) ) ;
186+ array. push ( Bump ( flag) ) ;
187+ array. push ( Bump ( flag) ) ;
188+
189+ let i = 2 ;
190+ let tail_len = array. len ( ) - i;
191+
192+ let res = catch_unwind ( AssertUnwindSafe ( || {
193+ array. truncate ( i) ;
194+ } ) ) ;
195+ assert ! ( res. is_err( ) ) ;
196+ // Check that all the tail elements drop, even if the first drop panics.
197+ assert_eq ! ( flag. get( ) , tail_len as i32 ) ;
198+ }
199+
200+
201+ }
202+
129203#[ test]
130204fn test_extend ( ) {
131205 let mut range = 0 ..10 ;
0 commit comments