@@ -7,6 +7,7 @@ use std::mem::{size_of, swap};
7
7
use std:: ops:: Bound :: * ;
8
8
use std:: panic:: { catch_unwind, AssertUnwindSafe } ;
9
9
use std:: rc:: Rc ;
10
+ use std:: sync:: atomic:: { AtomicU32 , Ordering } ;
10
11
use std:: vec:: { Drain , IntoIter } ;
11
12
12
13
struct DropCounter < ' a > {
@@ -2169,3 +2170,56 @@ fn test_vec_dedup() {
2169
2170
assert_eq ! ( vec, dedup) ;
2170
2171
}
2171
2172
}
2173
+
2174
+ #[ test]
2175
+ fn test_vec_dedup_panicking ( ) {
2176
+ #[ derive( Debug ) ]
2177
+ struct Panic {
2178
+ drop_counter : & ' static AtomicU32 ,
2179
+ value : bool ,
2180
+ index : usize ,
2181
+ }
2182
+
2183
+ impl PartialEq for Panic {
2184
+ fn eq ( & self , other : & Self ) -> bool {
2185
+ self . value == other. value
2186
+ }
2187
+ }
2188
+
2189
+ impl Drop for Panic {
2190
+ fn drop ( & mut self ) {
2191
+ let x = self . drop_counter . fetch_add ( 1 , Ordering :: SeqCst ) ;
2192
+ assert ! ( x != 4 ) ;
2193
+ }
2194
+ }
2195
+
2196
+ static DROP_COUNTER : AtomicU32 = AtomicU32 :: new ( 0 ) ;
2197
+ let expected = [
2198
+ Panic { drop_counter : & DROP_COUNTER , value : false , index : 0 } ,
2199
+ Panic { drop_counter : & DROP_COUNTER , value : false , index : 5 } ,
2200
+ Panic { drop_counter : & DROP_COUNTER , value : true , index : 6 } ,
2201
+ Panic { drop_counter : & DROP_COUNTER , value : true , index : 7 } ,
2202
+ ] ;
2203
+ let mut vec = vec ! [
2204
+ Panic { drop_counter: & DROP_COUNTER , value: false , index: 0 } ,
2205
+ // these elements get deduplicated
2206
+ Panic { drop_counter: & DROP_COUNTER , value: false , index: 1 } ,
2207
+ Panic { drop_counter: & DROP_COUNTER , value: false , index: 2 } ,
2208
+ Panic { drop_counter: & DROP_COUNTER , value: false , index: 3 } ,
2209
+ Panic { drop_counter: & DROP_COUNTER , value: false , index: 4 } ,
2210
+ // here it panics
2211
+ Panic { drop_counter: & DROP_COUNTER , value: false , index: 5 } ,
2212
+ Panic { drop_counter: & DROP_COUNTER , value: true , index: 6 } ,
2213
+ Panic { drop_counter: & DROP_COUNTER , value: true , index: 7 } ,
2214
+ ] ;
2215
+
2216
+ let _ = std:: panic:: catch_unwind ( std:: panic:: AssertUnwindSafe ( || {
2217
+ vec. dedup ( ) ;
2218
+ } ) ) ;
2219
+
2220
+ let ok = vec. iter ( ) . zip ( expected. iter ( ) ) . all ( |( x, y) | x. index == y. index ) ;
2221
+
2222
+ if !ok {
2223
+ panic ! ( "expected: {:?}\n got: {:?}\n " , expected, vec) ;
2224
+ }
2225
+ }
0 commit comments