]> git.proxmox.com Git - rustc.git/blame - src/test/ui/issues/issue-21486.rs
New upstream version 1.49.0+dfsg1
[rustc.git] / src / test / ui / issues / issue-21486.rs
CommitLineData
b7449926 1// run-pass
0bf4aa26 2#![allow(unreachable_code)]
9346a6ac
AL
3// Issue #21486: Make sure that all structures are dropped, even when
4// created via FRU and control-flow breaks in the middle of
5// construction.
6
62682a34 7use std::sync::atomic::{Ordering, AtomicUsize};
9346a6ac
AL
8
9#[derive(Debug)]
10struct Noisy(u8);
11impl Drop for Noisy {
12 fn drop(&mut self) {
13 // println!("splat #{}", self.0);
14 event(self.0);
15 }
16}
17
18#[allow(dead_code)]
19#[derive(Debug)]
20struct Foo { n0: Noisy, n1: Noisy }
21impl Foo {
22 fn vals(&self) -> (u8, u8) { (self.n0.0, self.n1.0) }
23}
24
25fn leak_1_ret() -> Foo {
26 let _old_foo = Foo { n0: Noisy(1), n1: Noisy(2) };
27 Foo { n0: { return Foo { n0: Noisy(3), n1: Noisy(4) } },
28 .._old_foo
29 };
30}
31
32fn leak_2_ret() -> Foo {
33 let _old_foo = Foo { n0: Noisy(1), n1: Noisy(2) };
34 Foo { n1: { return Foo { n0: Noisy(3), n1: Noisy(4) } },
35 .._old_foo
36 };
37}
38
39// In this case, the control flow break happens *before* we construct
40// `Foo(Noisy(1),Noisy(2))`, so there should be no record of it in the
41// event log.
42fn leak_3_ret() -> Foo {
43 let _old_foo = || Foo { n0: Noisy(1), n1: Noisy(2) };
44 Foo { n1: { return Foo { n0: Noisy(3), n1: Noisy(4) } },
45 .._old_foo()
46 };
47}
48
49pub fn main() {
50 reset_log();
51 assert_eq!(leak_1_ret().vals(), (3,4));
52 assert_eq!(0x01_02_03_04, event_log());
53
54 reset_log();
55 assert_eq!(leak_2_ret().vals(), (3,4));
56 assert_eq!(0x01_02_03_04, event_log());
57
58 reset_log();
59 assert_eq!(leak_3_ret().vals(), (3,4));
60 assert_eq!(0x03_04, event_log());
61}
62
62682a34 63static LOG: AtomicUsize = AtomicUsize::new(0);
9346a6ac
AL
64
65fn reset_log() {
66 LOG.store(0, Ordering::SeqCst);
67}
68
69fn event_log() -> usize {
70 LOG.load(Ordering::SeqCst)
71}
72
73fn event(tag: u8) {
74 let old_log = LOG.load(Ordering::SeqCst);
75 let new_log = (old_log << 8) + tag as usize;
76 LOG.store(new_log, Ordering::SeqCst);
77}