1
- // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
2
- #![ allow( static_mut_refs) ]
3
-
1
+ use std:: cell:: Cell ;
4
2
use std:: panic:: { AssertUnwindSafe , catch_unwind} ;
5
3
use std:: thread;
6
4
@@ -1027,21 +1025,26 @@ fn extract_if_drop_panic_leak() {
1027
1025
assert_eq ! ( d7. dropped( ) , 1 ) ;
1028
1026
}
1029
1027
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 ) ; }
1034
1031
1035
- #[ derive( Debug ) ]
1036
- struct D ( u32 ) ;
1032
+ struct $struct_name$( ( $elt_ty) ) ?;
1037
1033
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 ) ) ?
1042
1039
}
1043
1040
}
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 ) ;
1045
1048
1046
1049
let mut q = LinkedList :: new ( ) ;
1047
1050
q. push_back ( D ( 3 ) ) ;
@@ -1053,26 +1056,17 @@ fn extract_if_pred_panic_leak() {
1053
1056
q. push_front ( D ( 1 ) ) ;
1054
1057
q. push_front ( D ( 0 ) ) ;
1055
1058
1056
- catch_unwind ( AssertUnwindSafe ( || {
1059
+ _ = catch_unwind ( AssertUnwindSafe ( || {
1057
1060
q. extract_if ( |item| if item. 0 >= 2 { panic ! ( ) } else { true } ) . for_each ( drop)
1058
- } ) )
1059
- . ok ( ) ;
1061
+ } ) ) ;
1060
1062
1061
- assert_eq ! ( unsafe { DROPS } , 2 ) ; // 0 and 1
1063
+ assert_eq ! ( DROPS . get ( ) , 2 ) ; // 0 and 1
1062
1064
assert_eq ! ( q. len( ) , 6 ) ;
1063
1065
}
1064
1066
1065
1067
#[ test]
1066
1068
fn 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 ) ;
1076
1070
1077
1071
let mut ring = LinkedList :: new ( ) ;
1078
1072
ring. push_back ( Elem ) ;
@@ -1081,20 +1075,12 @@ fn test_drop() {
1081
1075
ring. push_front ( Elem ) ;
1082
1076
drop ( ring) ;
1083
1077
1084
- assert_eq ! ( unsafe { DROPS } , 4 ) ;
1078
+ assert_eq ! ( DROPS . get ( ) , 4 ) ;
1085
1079
}
1086
1080
1087
1081
#[ test]
1088
1082
fn 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 ) ;
1098
1084
1099
1085
let mut ring = LinkedList :: new ( ) ;
1100
1086
ring. push_back ( Elem ) ;
@@ -1104,54 +1090,32 @@ fn test_drop_with_pop() {
1104
1090
1105
1091
drop ( ring. pop_back ( ) ) ;
1106
1092
drop ( ring. pop_front ( ) ) ;
1107
- assert_eq ! ( unsafe { DROPS } , 2 ) ;
1093
+ assert_eq ! ( DROPS . get ( ) , 2 ) ;
1108
1094
1109
1095
drop ( ring) ;
1110
- assert_eq ! ( unsafe { DROPS } , 4 ) ;
1096
+ assert_eq ! ( DROPS . get ( ) , 4 ) ;
1111
1097
}
1112
1098
1113
1099
#[ test]
1114
1100
fn 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 ) ;
1124
1102
1125
1103
let mut ring = LinkedList :: new ( ) ;
1126
1104
ring. push_back ( Elem ) ;
1127
1105
ring. push_front ( Elem ) ;
1128
1106
ring. push_back ( Elem ) ;
1129
1107
ring. push_front ( Elem ) ;
1130
1108
ring. clear ( ) ;
1131
- assert_eq ! ( unsafe { DROPS } , 4 ) ;
1109
+ assert_eq ! ( DROPS . get ( ) , 4 ) ;
1132
1110
1133
1111
drop ( ring) ;
1134
- assert_eq ! ( unsafe { DROPS } , 4 ) ;
1112
+ assert_eq ! ( DROPS . get ( ) , 4 ) ;
1135
1113
}
1136
1114
1137
1115
#[ test]
1138
1116
#[ cfg_attr( not( panic = "unwind" ) , ignore = "test requires unwinding support" ) ]
1139
1117
fn 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`" ) ; } ) ;
1155
1119
1156
1120
let mut q = LinkedList :: new ( ) ;
1157
1121
q. push_back ( D ( false ) ) ;
@@ -1165,7 +1129,7 @@ fn test_drop_panic() {
1165
1129
1166
1130
catch_unwind ( move || drop ( q) ) . ok ( ) ;
1167
1131
1168
- assert_eq ! ( unsafe { DROPS } , 8 ) ;
1132
+ assert_eq ! ( DROPS . get ( ) , 8 ) ;
1169
1133
}
1170
1134
1171
1135
#[ test]
0 commit comments