]> git.lizzy.rs Git - rust.git/blob - src/test/run-pass/issue-23338-ensure-param-drop-order.rs
507d482febfd90b089154059cbce53a8848c461b
[rust.git] / src / test / run-pass / issue-23338-ensure-param-drop-order.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 // ignore-pretty : (#23623) problems when  ending with // comments
12
13 // This test is ensuring that parameters are indeed dropped after
14 // temporaries in a fn body.
15
16 use std::cell::RefCell;
17
18 use self::d::D;
19
20 pub fn main() {
21     let log = RefCell::new(vec![]);
22     d::println("created empty log");
23     test(&log);
24
25     assert_eq!(&log.borrow()[..],
26                [
27                    //                                    created empty log
28                    //    +-- Make D(da_0, 0)
29                    //    | +-- Make D(de_1, 1)
30                    //    | |                             calling foo
31                    //    | |                             entered foo
32                    //    | | +-- Make D(de_2, 2)
33                    //    | | | +-- Make D(da_1, 3)
34                    //    | | | | +-- Make D(de_3, 4)
35                    //    | | | | | +-- Make D(de_4, 5)
36                    3, // | | | +-- Drop D(da_1, 3)
37                    //    | | |   | |
38                    4, // | | |   +-- Drop D(de_3, 4)
39                    //    | | |     |
40                    //    | | |     |                     eval tail of foo
41                    //    | | | +-- Make D(de_5, 6)
42                    //    | | | | +-- Make D(de_6, 7)
43                    6, // | | | +-- Drop D(de_5, 6)
44                    //    | | |   | |
45                    5, // | | |   | +-- Drop D(de_4, 5)
46                    //    | | |   |
47                    2, // | | +-- Drop D(de_2, 2)
48                    //    | |     |
49                    1, // | +-- Drop D(de_1, 1)
50                    //    |       |
51                    0, // +-- Drop D(da_0, 0)
52                    //            |
53                    //            |                       result D(de_6, 7)
54                    7 //          +-- Drop D(de_6, 7)
55
56                        ]);
57 }
58
59 fn test<'a>(log: d::Log<'a>) {
60     let da = D::new("da", 0, log);
61     let de = D::new("de", 1, log);
62     d::println("calling foo");
63     let result = foo(da, de);
64     d::println(&format!("result {}", result));
65 }
66
67 fn foo<'a>(da0: D<'a>, de1: D<'a>) -> D<'a> {
68     d::println("entered foo");
69     let de2 = de1.incr();      // creates D(de_2, 2)
70     let de4 = {
71         let _da1 = da0.incr(); // creates D(da_1, 3)
72         de2.incr().incr()      // creates D(de_3, 4) and D(de_4, 5)
73     };
74     d::println("eval tail of foo");
75     de4.incr().incr()          // creates D(de_5, 6) and D(de_6, 7)
76 }
77
78 // This module provides simultaneous printouts of the dynamic extents
79 // of all of the D values, in addition to logging the order that each
80 // is dropped.
81
82 const PREF_INDENT: u32 = 16;
83
84 pub mod d {
85     #![allow(unused_parens)]
86     use std::fmt;
87     use std::mem;
88     use std::cell::RefCell;
89
90     static mut counter: u32 = 0;
91     static mut trails: u64 = 0;
92
93     pub type Log<'a> = &'a RefCell<Vec<u32>>;
94
95     pub fn current_width() -> u32 {
96         unsafe { max_width() - trails.leading_zeros() }
97     }
98
99     pub fn max_width() -> u32 {
100         unsafe {
101             (mem::size_of_val(&trails)*8) as u32
102         }
103     }
104
105     pub fn indent_println(my_trails: u32, s: &str) {
106         let mut indent: String = String::new();
107         for i in 0..my_trails {
108             unsafe {
109                 if trails & (1 << i) != 0 {
110                     indent = indent + "| ";
111                 } else {
112                     indent = indent + "  ";
113                 }
114             }
115         }
116         println!("{}{}", indent, s);
117     }
118
119     pub fn println(s: &str) {
120         indent_println(super::PREF_INDENT, s);
121     }
122
123     fn first_avail() -> u32 {
124         unsafe {
125             for i in 0..64 {
126                 if trails & (1 << i) == 0 {
127                     return i;
128                 }
129             }
130         }
131         panic!("exhausted trails");
132     }
133
134     pub struct D<'a> {
135         name: &'static str, i: u32, uid: u32, trail: u32, log: Log<'a>
136     }
137
138     impl<'a> fmt::Display for D<'a> {
139         fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
140             write!(w, "D({}_{}, {})", self.name, self.i, self.uid)
141         }
142     }
143
144     impl<'a> D<'a> {
145         pub fn new(name: &'static str, i: u32, log: Log<'a>) -> D<'a> {
146             unsafe {
147                 let trail = first_avail();
148                 let ctr = counter;
149                 counter += 1;
150                 trails |= (1 << trail);
151                 let ret = D {
152                     name: name, i: i, log: log, uid: ctr, trail: trail
153                 };
154                 indent_println(trail, &format!("+-- Make {}", ret));
155                 ret
156             }
157         }
158         pub fn incr(&self) -> D<'a> {
159             D::new(self.name, self.i + 1, self.log)
160         }
161     }
162
163     impl<'a> Drop for D<'a> {
164         fn drop(&mut self) {
165             unsafe { trails &= !(1 << self.trail); };
166             self.log.borrow_mut().push(self.uid);
167             indent_println(self.trail, &format!("+-- Drop {}", self));
168             indent_println(::PREF_INDENT, "");
169         }
170     }
171 }