1 // run-pass
2 
3 #![allow(unused_variables)]
4 #![allow(unused_imports)]
5 // ignore-wasm32-bare compiled with panic=abort by default
6 
7 // Test that builtin implementations of `Clone` cleanup everything
8 // in case of unwinding.
9 
10 use std::thread;
11 use std::rc::Rc;
12 
13 struct S(Rc<()>);
14 
15 impl Clone for S {
clone(&self) -> Self16     fn clone(&self) -> Self {
17         if Rc::strong_count(&self.0) == 7 {
18             panic!("oops");
19         }
20 
21         S(self.0.clone())
22     }
23 }
24 
main()25 fn main() {
26     let counter = Rc::new(());
27 
28     // Unwinding with tuples...
29     let ccounter = counter.clone();
30     let result = std::panic::catch_unwind(move || {
31         let _ = (
32             S(ccounter.clone()),
33             S(ccounter.clone()),
34             S(ccounter.clone()),
35             S(ccounter)
36         ).clone();
37     });
38 
39     assert!(result.is_err());
40     assert_eq!(
41         1,
42         Rc::strong_count(&counter)
43     );
44 
45     // ... and with arrays.
46     let ccounter = counter.clone();
47     let child = std::panic::catch_unwind(move || {
48         let _ = [
49             S(ccounter.clone()),
50             S(ccounter.clone()),
51             S(ccounter.clone()),
52             S(ccounter)
53         ].clone();
54     });
55 
56     assert!(child.is_err());
57     assert_eq!(
58         1,
59         Rc::strong_count(&counter)
60     );
61 }
62