1- // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
2- #![ allow( static_mut_refs) ]
3-
1+ use std:: cell:: Cell ;
42use std:: panic:: { AssertUnwindSafe , catch_unwind} ;
53use std:: thread;
64
@@ -1027,21 +1025,26 @@ fn extract_if_drop_panic_leak() {
10271025 assert_eq ! ( d7. dropped( ) , 1 ) ;
10281026}
10291027
1030- #[ test]
1031- #[ cfg_attr( not( panic = "unwind" ) , ignore = "test requires unwinding support" ) ]
1032- fn extract_if_pred_panic_leak ( ) {
1033- static mut DROPS : i32 = 0 ;
1028+ macro_rules! struct_with_counted_drop {
1029+ ( $struct_name: ident$( ( $elt_ty: ty) ) ?, $drop_counter: ident $( => $drop_stmt: expr) ?) => {
1030+ thread_local! { static $drop_counter: Cell <i32 > = Cell :: new( 0 ) ; }
10341031
1035- #[ derive( Debug ) ]
1036- struct D ( u32 ) ;
1032+ struct $struct_name$( ( $elt_ty) ) ?;
10371033
1038- impl Drop for D {
1039- fn drop ( & mut self ) {
1040- unsafe {
1041- DROPS += 1 ;
1034+ impl Drop for $struct_name {
1035+ fn drop( & mut self ) {
1036+ $drop_counter. set( $drop_counter. get( ) + 1 ) ;
1037+
1038+ $( $drop_stmt( self ) ) ?
10421039 }
10431040 }
1044- }
1041+ } ;
1042+ }
1043+
1044+ #[ test]
1045+ #[ cfg_attr( not( panic = "unwind" ) , ignore = "test requires unwinding support" ) ]
1046+ fn extract_if_pred_panic_leak ( ) {
1047+ struct_with_counted_drop ! ( D ( u32 ) , DROPS ) ;
10451048
10461049 let mut q = LinkedList :: new ( ) ;
10471050 q. push_back ( D ( 3 ) ) ;
@@ -1053,26 +1056,17 @@ fn extract_if_pred_panic_leak() {
10531056 q. push_front ( D ( 1 ) ) ;
10541057 q. push_front ( D ( 0 ) ) ;
10551058
1056- catch_unwind ( AssertUnwindSafe ( || {
1059+ _ = catch_unwind ( AssertUnwindSafe ( || {
10571060 q. extract_if ( |item| if item. 0 >= 2 { panic ! ( ) } else { true } ) . for_each ( drop)
1058- } ) )
1059- . ok ( ) ;
1061+ } ) ) ;
10601062
1061- assert_eq ! ( unsafe { DROPS } , 2 ) ; // 0 and 1
1063+ assert_eq ! ( DROPS . get ( ) , 2 ) ; // 0 and 1
10621064 assert_eq ! ( q. len( ) , 6 ) ;
10631065}
10641066
10651067#[ test]
10661068fn test_drop ( ) {
1067- static mut DROPS : i32 = 0 ;
1068- struct Elem ;
1069- impl Drop for Elem {
1070- fn drop ( & mut self ) {
1071- unsafe {
1072- DROPS += 1 ;
1073- }
1074- }
1075- }
1069+ struct_with_counted_drop ! ( Elem , DROPS ) ;
10761070
10771071 let mut ring = LinkedList :: new ( ) ;
10781072 ring. push_back ( Elem ) ;
@@ -1081,20 +1075,12 @@ fn test_drop() {
10811075 ring. push_front ( Elem ) ;
10821076 drop ( ring) ;
10831077
1084- assert_eq ! ( unsafe { DROPS } , 4 ) ;
1078+ assert_eq ! ( DROPS . get ( ) , 4 ) ;
10851079}
10861080
10871081#[ test]
10881082fn test_drop_with_pop ( ) {
1089- static mut DROPS : i32 = 0 ;
1090- struct Elem ;
1091- impl Drop for Elem {
1092- fn drop ( & mut self ) {
1093- unsafe {
1094- DROPS += 1 ;
1095- }
1096- }
1097- }
1083+ struct_with_counted_drop ! ( Elem , DROPS ) ;
10981084
10991085 let mut ring = LinkedList :: new ( ) ;
11001086 ring. push_back ( Elem ) ;
@@ -1104,54 +1090,32 @@ fn test_drop_with_pop() {
11041090
11051091 drop ( ring. pop_back ( ) ) ;
11061092 drop ( ring. pop_front ( ) ) ;
1107- assert_eq ! ( unsafe { DROPS } , 2 ) ;
1093+ assert_eq ! ( DROPS . get ( ) , 2 ) ;
11081094
11091095 drop ( ring) ;
1110- assert_eq ! ( unsafe { DROPS } , 4 ) ;
1096+ assert_eq ! ( DROPS . get ( ) , 4 ) ;
11111097}
11121098
11131099#[ test]
11141100fn test_drop_clear ( ) {
1115- static mut DROPS : i32 = 0 ;
1116- struct Elem ;
1117- impl Drop for Elem {
1118- fn drop ( & mut self ) {
1119- unsafe {
1120- DROPS += 1 ;
1121- }
1122- }
1123- }
1101+ struct_with_counted_drop ! ( Elem , DROPS ) ;
11241102
11251103 let mut ring = LinkedList :: new ( ) ;
11261104 ring. push_back ( Elem ) ;
11271105 ring. push_front ( Elem ) ;
11281106 ring. push_back ( Elem ) ;
11291107 ring. push_front ( Elem ) ;
11301108 ring. clear ( ) ;
1131- assert_eq ! ( unsafe { DROPS } , 4 ) ;
1109+ assert_eq ! ( DROPS . get ( ) , 4 ) ;
11321110
11331111 drop ( ring) ;
1134- assert_eq ! ( unsafe { DROPS } , 4 ) ;
1112+ assert_eq ! ( DROPS . get ( ) , 4 ) ;
11351113}
11361114
11371115#[ test]
11381116#[ cfg_attr( not( panic = "unwind" ) , ignore = "test requires unwinding support" ) ]
11391117fn test_drop_panic ( ) {
1140- static mut DROPS : i32 = 0 ;
1141-
1142- struct D ( bool ) ;
1143-
1144- impl Drop for D {
1145- fn drop ( & mut self ) {
1146- unsafe {
1147- DROPS += 1 ;
1148- }
1149-
1150- if self . 0 {
1151- panic ! ( "panic in `drop`" ) ;
1152- }
1153- }
1154- }
1118+ struct_with_counted_drop ! ( D ( bool ) , DROPS => |this: & D | if this. 0 { panic!( "panic in `drop`" ) ; } ) ;
11551119
11561120 let mut q = LinkedList :: new ( ) ;
11571121 q. push_back ( D ( false ) ) ;
@@ -1165,7 +1129,7 @@ fn test_drop_panic() {
11651129
11661130 catch_unwind ( move || drop ( q) ) . ok ( ) ;
11671131
1168- assert_eq ! ( unsafe { DROPS } , 8 ) ;
1132+ assert_eq ! ( DROPS . get ( ) , 8 ) ;
11691133}
11701134
11711135#[ test]
0 commit comments