File tree 1 file changed +41
-0
lines changed
1 file changed +41
-0
lines changed Original file line number Diff line number Diff line change @@ -241,3 +241,44 @@ fn iterator_drops() {
241
241
}
242
242
assert_eq ! ( i. get( ) , 5 ) ;
243
243
}
244
+
245
+ #[ test]
246
+ fn array_default_impl_avoids_leaks_on_panic ( ) {
247
+ use core:: sync:: atomic:: { AtomicUsize , Ordering :: Relaxed } ;
248
+ static COUNTER : AtomicUsize = AtomicUsize :: new ( 0 ) ;
249
+ #[ derive( Debug ) ]
250
+ struct Bomb ( usize ) ;
251
+
252
+ impl Default for Bomb {
253
+ fn default ( ) -> Bomb {
254
+ if COUNTER . load ( Relaxed ) == 3 {
255
+ panic ! ( "bomb limit exceeded" ) ;
256
+ }
257
+
258
+ COUNTER . fetch_add ( 1 , Relaxed ) ;
259
+ Bomb ( COUNTER . load ( Relaxed ) )
260
+ }
261
+ }
262
+
263
+ impl Drop for Bomb {
264
+ fn drop ( & mut self ) {
265
+ COUNTER . fetch_sub ( 1 , Relaxed ) ;
266
+ }
267
+ }
268
+
269
+ let res = std:: panic:: catch_unwind ( || <[ Bomb ; 5 ] >:: default ( ) ) ;
270
+ let panic_msg = match res {
271
+ Ok ( _) => unreachable ! ( ) ,
272
+ Err ( p) => p. downcast :: < & ' static str > ( ) . unwrap ( ) ,
273
+ } ;
274
+ assert_eq ! ( * panic_msg, "bomb limit exceeded" ) ;
275
+ // check that all bombs are successfully dropped
276
+ assert_eq ! ( COUNTER . load( Relaxed ) , 0 ) ;
277
+ }
278
+
279
+ #[ test]
280
+ fn empty_array_is_always_default ( ) {
281
+ struct DoesNotImplDefault ;
282
+
283
+ let _arr = <[ DoesNotImplDefault ; 0 ] >:: default ( ) ;
284
+ }
You can’t perform that action at this time.
0 commit comments