]> git.lizzy.rs Git - rust.git/blob - src/test/ui/drop/drop-trait-enum.rs
Rollup merge of #98640 - cuviper:stable-rust-analyzer, r=Mark-Simulacrum
[rust.git] / src / test / ui / drop / drop-trait-enum.rs
1 // run-pass
2 #![allow(dead_code)]
3 #![allow(unused_assignments)]
4 #![allow(unused_variables)]
5 // ignore-emscripten no threads support
6 // needs-unwind
7
8 use std::thread;
9 use std::sync::mpsc::{channel, Sender};
10
11 #[derive(PartialEq, Debug)]
12 enum Message {
13     Dropped,
14     DestructorRan
15 }
16
17 struct SendOnDrop {
18     sender: Sender<Message>
19 }
20
21 impl Drop for SendOnDrop {
22     fn drop(&mut self) {
23         self.sender.send(Message::Dropped).unwrap();
24     }
25 }
26
27 enum Foo {
28     SimpleVariant(Sender<Message>),
29     NestedVariant(Box<usize>, SendOnDrop, Sender<Message>),
30     FailingVariant { on_drop: SendOnDrop }
31 }
32
33 impl Drop for Foo {
34     fn drop(&mut self) {
35         match self {
36             &mut Foo::SimpleVariant(ref mut sender) => {
37                 sender.send(Message::DestructorRan).unwrap();
38             }
39             &mut Foo::NestedVariant(_, _, ref mut sender) => {
40                 sender.send(Message::DestructorRan).unwrap();
41             }
42             &mut Foo::FailingVariant { .. } => {
43                 panic!("Failed");
44             }
45         }
46     }
47 }
48
49 pub fn main() {
50     let (sender, receiver) = channel();
51     {
52         let v = Foo::SimpleVariant(sender);
53     }
54     assert_eq!(receiver.recv().unwrap(), Message::DestructorRan);
55     assert_eq!(receiver.recv().ok(), None);
56
57     let (sender, receiver) = channel();
58     {
59         let v = Foo::NestedVariant(Box::new(42), SendOnDrop { sender: sender.clone() }, sender);
60     }
61     assert_eq!(receiver.recv().unwrap(), Message::DestructorRan);
62     assert_eq!(receiver.recv().unwrap(), Message::Dropped);
63     assert_eq!(receiver.recv().ok(), None);
64
65     let (sender, receiver) = channel();
66     let t = thread::spawn(move|| {
67         let v = Foo::FailingVariant { on_drop: SendOnDrop { sender: sender } };
68     });
69     assert_eq!(receiver.recv().unwrap(), Message::Dropped);
70     assert_eq!(receiver.recv().ok(), None);
71     drop(t.join());
72
73     let (sender, receiver) = channel();
74     let t = {
75         thread::spawn(move|| {
76             let mut v = Foo::NestedVariant(Box::new(42), SendOnDrop {
77                 sender: sender.clone()
78             }, sender.clone());
79             v = Foo::NestedVariant(Box::new(42),
80                                    SendOnDrop { sender: sender.clone() },
81                                    sender.clone());
82             v = Foo::SimpleVariant(sender.clone());
83             v = Foo::FailingVariant { on_drop: SendOnDrop { sender: sender } };
84         })
85     };
86     assert_eq!(receiver.recv().unwrap(), Message::DestructorRan);
87     assert_eq!(receiver.recv().unwrap(), Message::Dropped);
88     assert_eq!(receiver.recv().unwrap(), Message::DestructorRan);
89     assert_eq!(receiver.recv().unwrap(), Message::Dropped);
90     assert_eq!(receiver.recv().unwrap(), Message::DestructorRan);
91     assert_eq!(receiver.recv().unwrap(), Message::Dropped);
92     assert_eq!(receiver.recv().ok(), None);
93     drop(t.join());
94 }