File tree Expand file tree Collapse file tree 1 file changed +41
-0
lines changed Expand file tree Collapse file tree 1 file changed +41
-0
lines changed Original file line number Diff line number Diff line change @@ -241,3 +241,44 @@ fn iterator_drops() {
241241 }
242242 assert_eq ! ( i. get( ) , 5 ) ;
243243}
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