@@ -7,6 +7,7 @@ use std::mem::{size_of, swap};
77use std:: ops:: Bound :: * ;
88use std:: panic:: { catch_unwind, AssertUnwindSafe } ;
99use std:: rc:: Rc ;
10+ use std:: sync:: atomic:: { AtomicU32 , Ordering } ;
1011use std:: vec:: { Drain , IntoIter } ;
1112
1213struct DropCounter < ' a > {
@@ -2169,3 +2170,56 @@ fn test_vec_dedup() {
21692170 assert_eq ! ( vec, dedup) ;
21702171 }
21712172}
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