]> git.proxmox.com Git - rustc.git/blame - src/test/run-pass/issue-21486.rs
New upstream version 1.19.0+dfsg1
[rustc.git] / src / test / run-pass / issue-21486.rs
CommitLineData
9346a6ac
AL
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
62682a34 15#![feature(const_fn)]
9346a6ac 16
62682a34 17use std::sync::atomic::{Ordering, AtomicUsize};
9346a6ac
AL
18
19#[derive(Debug)]
20struct Noisy(u8);
21impl 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)]
30struct Foo { n0: Noisy, n1: Noisy }
31impl Foo {
32 fn vals(&self) -> (u8, u8) { (self.n0.0, self.n1.0) }
33}
34
35fn 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
42fn 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.
52fn 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
59pub 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
62682a34 73static LOG: AtomicUsize = AtomicUsize::new(0);
9346a6ac
AL
74
75fn reset_log() {
76 LOG.store(0, Ordering::SeqCst);
77}
78
79fn event_log() -> usize {
80 LOG.load(Ordering::SeqCst)
81}
82
83fn 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}