]>
Commit | Line | Data |
---|---|---|
064997fb | 1 | // run-pass |
f2b60f7d | 2 | // compile-flags: -Zvalidate-mir |
064997fb FG |
3 | |
4 | use std::fmt::Display; | |
5 | use std::rc::Rc; | |
6 | use std::sync::atomic::{AtomicU8, Ordering}; | |
7 | ||
8 | static TRACKER: AtomicU8 = AtomicU8::new(0); | |
9 | ||
10 | #[derive(Default)] | |
11 | struct Droppy { | |
12 | inner: u32, | |
13 | } | |
14 | ||
15 | impl Drop for Droppy { | |
16 | fn drop(&mut self) { | |
17 | TRACKER.store(1, Ordering::Release); | |
18 | println!("I've been dropped"); | |
19 | } | |
20 | } | |
21 | ||
22 | fn foo<'a>(x: &'a str) -> Result<impl Display + 'a, ()> { | |
23 | Ok(x) | |
24 | } | |
25 | ||
26 | fn main() { | |
27 | assert_eq!(TRACKER.load(Ordering::Acquire), 0); | |
28 | let 0 = Droppy::default().inner else { return }; | |
29 | assert_eq!(TRACKER.load(Ordering::Acquire), 1); | |
30 | println!("Should have dropped 👆"); | |
31 | ||
32 | { | |
33 | // cf. https://github.com/rust-lang/rust/pull/99518#issuecomment-1191520030 | |
34 | struct Foo<'a>(&'a mut u32); | |
35 | ||
36 | impl<'a> Drop for Foo<'a> { | |
37 | fn drop(&mut self) { | |
38 | *self.0 = 0; | |
39 | } | |
40 | } | |
41 | let mut foo = 0; | |
42 | let Foo(0) = Foo(&mut foo) else { | |
43 | *&mut foo = 1; | |
44 | todo!() | |
45 | }; | |
46 | } | |
47 | { | |
48 | let x = String::from("Hey"); | |
49 | ||
50 | let Ok(s) = foo(&x) else { panic!() }; | |
51 | assert_eq!(s.to_string(), x); | |
52 | } | |
53 | { | |
54 | // test let-else drops temps after statement | |
55 | let rc = Rc::new(0); | |
56 | let 0 = *rc.clone() else { unreachable!() }; | |
57 | Rc::try_unwrap(rc).unwrap(); | |
58 | } | |
59 | { | |
60 | let mut rc = Rc::new(0); | |
61 | let mut i = 0; | |
62 | loop { | |
63 | if i > 3 { | |
64 | break; | |
65 | } | |
66 | let 1 = *rc.clone() else { | |
67 | if let Ok(v) = Rc::try_unwrap(rc) { | |
68 | rc = Rc::new(v); | |
69 | } else { | |
70 | panic!() | |
71 | } | |
72 | i += 1; | |
73 | continue | |
74 | }; | |
75 | } | |
76 | } | |
f2b60f7d FG |
77 | { |
78 | fn must_pass() { | |
79 | let rc = Rc::new(()); | |
80 | let &None = &Some(Rc::clone(&rc)) else { | |
81 | Rc::try_unwrap(rc).unwrap(); | |
82 | return; | |
83 | }; | |
84 | unreachable!(); | |
85 | } | |
86 | must_pass(); | |
87 | } | |
064997fb FG |
88 | { |
89 | // test let-else drops temps before else block | |
90 | // NOTE: this test has to be the last block in the `main` | |
91 | // body. | |
92 | let rc = Rc::new(0); | |
93 | let 1 = *rc.clone() else { | |
94 | Rc::try_unwrap(rc).unwrap(); | |
95 | return; | |
96 | }; | |
97 | unreachable!(); | |
98 | } | |
99 | } |