]> git.proxmox.com Git - rustc.git/blob - src/test/run-pass/issue-21486.rs
Imported Upstream version 1.2.0+dfsg1
[rustc.git] / src / test / run-pass / issue-21486.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // Issue #21486: Make sure that all structures are dropped, even when
12 // created via FRU and control-flow breaks in the middle of
13 // construction.
14
15 #![feature(const_fn)]
16
17 use std::sync::atomic::{Ordering, AtomicUsize};
18
19 #[derive(Debug)]
20 struct Noisy(u8);
21 impl Drop for Noisy {
22 fn drop(&mut self) {
23 // println!("splat #{}", self.0);
24 event(self.0);
25 }
26 }
27
28 #[allow(dead_code)]
29 #[derive(Debug)]
30 struct Foo { n0: Noisy, n1: Noisy }
31 impl Foo {
32 fn vals(&self) -> (u8, u8) { (self.n0.0, self.n1.0) }
33 }
34
35 fn leak_1_ret() -> Foo {
36 let _old_foo = Foo { n0: Noisy(1), n1: Noisy(2) };
37 Foo { n0: { return Foo { n0: Noisy(3), n1: Noisy(4) } },
38 .._old_foo
39 };
40 }
41
42 fn leak_2_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
49 // In this case, the control flow break happens *before* we construct
50 // `Foo(Noisy(1),Noisy(2))`, so there should be no record of it in the
51 // event log.
52 fn leak_3_ret() -> Foo {
53 let _old_foo = || Foo { n0: Noisy(1), n1: Noisy(2) };
54 Foo { n1: { return Foo { n0: Noisy(3), n1: Noisy(4) } },
55 .._old_foo()
56 };
57 }
58
59 pub fn main() {
60 reset_log();
61 assert_eq!(leak_1_ret().vals(), (3,4));
62 assert_eq!(0x01_02_03_04, event_log());
63
64 reset_log();
65 assert_eq!(leak_2_ret().vals(), (3,4));
66 assert_eq!(0x01_02_03_04, event_log());
67
68 reset_log();
69 assert_eq!(leak_3_ret().vals(), (3,4));
70 assert_eq!(0x03_04, event_log());
71 }
72
73 static LOG: AtomicUsize = AtomicUsize::new(0);
74
75 fn reset_log() {
76 LOG.store(0, Ordering::SeqCst);
77 }
78
79 fn event_log() -> usize {
80 LOG.load(Ordering::SeqCst)
81 }
82
83 fn event(tag: u8) {
84 let old_log = LOG.load(Ordering::SeqCst);
85 let new_log = (old_log << 8) + tag as usize;
86 LOG.store(new_log, Ordering::SeqCst);
87 }