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