]>
Commit | Line | Data |
---|---|---|
b7449926 | 1 | // run-pass |
0bf4aa26 XL |
2 | #![allow(dead_code)] |
3 | #![allow(unused_assignments)] | |
4 | #![allow(unused_variables)] | |
5bcae85e | 5 | // ignore-emscripten no threads support |
a2a8927a | 6 | // needs-unwind |
5bcae85e | 7 | |
85aaf69f | 8 | use std::thread; |
1a4d82fc JJ |
9 | use std::sync::mpsc::{channel, Sender}; |
10 | ||
85aaf69f | 11 | #[derive(PartialEq, Debug)] |
1a4d82fc JJ |
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>), | |
c34b1796 | 29 | NestedVariant(Box<usize>, SendOnDrop, Sender<Message>), |
1a4d82fc JJ |
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 | { | |
c295e0f8 | 59 | let v = Foo::NestedVariant(Box::new(42), SendOnDrop { sender: sender.clone() }, sender); |
1a4d82fc JJ |
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(); | |
85aaf69f | 66 | let t = thread::spawn(move|| { |
1a4d82fc JJ |
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); | |
85aaf69f | 71 | drop(t.join()); |
1a4d82fc JJ |
72 | |
73 | let (sender, receiver) = channel(); | |
85aaf69f SL |
74 | let t = { |
75 | thread::spawn(move|| { | |
c295e0f8 | 76 | let mut v = Foo::NestedVariant(Box::new(42), SendOnDrop { |
1a4d82fc JJ |
77 | sender: sender.clone() |
78 | }, sender.clone()); | |
c295e0f8 | 79 | v = Foo::NestedVariant(Box::new(42), |
85aaf69f SL |
80 | SendOnDrop { sender: sender.clone() }, |
81 | sender.clone()); | |
1a4d82fc JJ |
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); | |
85aaf69f | 93 | drop(t.join()); |
1a4d82fc | 94 | } |