]>
Commit | Line | Data |
---|---|---|
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 | ||
c30ab7b3 | 11 | // ignore-pretty issue #37201 |
9346a6ac AL |
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![]); | |
92a42be0 | 22 | d::println("created empty log"); |
9346a6ac AL |
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) | |
a7813a04 XL |
43 | 5, // | | | | | +-- Drop D(de_4, 5) |
44 | // | | | | | | |
9346a6ac | 45 | 2, // | | +-- Drop D(de_2, 2) |
a7813a04 XL |
46 | // | | | | |
47 | 6, // | | +-- Drop D(de_5, 6) | |
9346a6ac AL |
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); | |
92a42be0 | 62 | d::println("calling foo"); |
9346a6ac AL |
63 | let result = foo(da, de); |
64 | d::println(&format!("result {}", result)); | |
65 | } | |
66 | ||
a7813a04 XL |
67 | // FIXME(#33490) Remove the double braces when old trans is gone. |
68 | fn foo<'a>(da0: D<'a>, de1: D<'a>) -> D<'a> {{ | |
92a42be0 | 69 | d::println("entered foo"); |
9346a6ac AL |
70 | let de2 = de1.incr(); // creates D(de_2, 2) |
71 | let de4 = { | |
72 | let _da1 = da0.incr(); // creates D(da_1, 3) | |
73 | de2.incr().incr() // creates D(de_3, 4) and D(de_4, 5) | |
74 | }; | |
92a42be0 | 75 | d::println("eval tail of foo"); |
9346a6ac | 76 | de4.incr().incr() // creates D(de_5, 6) and D(de_6, 7) |
a7813a04 | 77 | }} |
9346a6ac AL |
78 | |
79 | // This module provides simultaneous printouts of the dynamic extents | |
80 | // of all of the D values, in addition to logging the order that each | |
81 | // is dropped. | |
82 | ||
83 | const PREF_INDENT: u32 = 16; | |
84 | ||
85 | pub mod d { | |
86 | #![allow(unused_parens)] | |
87 | use std::fmt; | |
88 | use std::mem; | |
89 | use std::cell::RefCell; | |
90 | ||
91 | static mut counter: u32 = 0; | |
92 | static mut trails: u64 = 0; | |
93 | ||
94 | pub type Log<'a> = &'a RefCell<Vec<u32>>; | |
95 | ||
96 | pub fn current_width() -> u32 { | |
97 | unsafe { max_width() - trails.leading_zeros() } | |
98 | } | |
99 | ||
100 | pub fn max_width() -> u32 { | |
101 | unsafe { | |
102 | (mem::size_of_val(&trails)*8) as u32 | |
103 | } | |
104 | } | |
105 | ||
106 | pub fn indent_println(my_trails: u32, s: &str) { | |
107 | let mut indent: String = String::new(); | |
108 | for i in 0..my_trails { | |
109 | unsafe { | |
110 | if trails & (1 << i) != 0 { | |
111 | indent = indent + "| "; | |
112 | } else { | |
113 | indent = indent + " "; | |
114 | } | |
115 | } | |
116 | } | |
117 | println!("{}{}", indent, s); | |
118 | } | |
119 | ||
120 | pub fn println(s: &str) { | |
121 | indent_println(super::PREF_INDENT, s); | |
122 | } | |
123 | ||
124 | fn first_avail() -> u32 { | |
125 | unsafe { | |
126 | for i in 0..64 { | |
127 | if trails & (1 << i) == 0 { | |
128 | return i; | |
129 | } | |
130 | } | |
131 | } | |
132 | panic!("exhausted trails"); | |
133 | } | |
134 | ||
135 | pub struct D<'a> { | |
136 | name: &'static str, i: u32, uid: u32, trail: u32, log: Log<'a> | |
137 | } | |
138 | ||
139 | impl<'a> fmt::Display for D<'a> { | |
140 | fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { | |
141 | write!(w, "D({}_{}, {})", self.name, self.i, self.uid) | |
142 | } | |
143 | } | |
144 | ||
145 | impl<'a> D<'a> { | |
146 | pub fn new(name: &'static str, i: u32, log: Log<'a>) -> D<'a> { | |
147 | unsafe { | |
148 | let trail = first_avail(); | |
149 | let ctr = counter; | |
150 | counter += 1; | |
151 | trails |= (1 << trail); | |
152 | let ret = D { | |
153 | name: name, i: i, log: log, uid: ctr, trail: trail | |
154 | }; | |
155 | indent_println(trail, &format!("+-- Make {}", ret)); | |
156 | ret | |
157 | } | |
158 | } | |
159 | pub fn incr(&self) -> D<'a> { | |
160 | D::new(self.name, self.i + 1, self.log) | |
161 | } | |
162 | } | |
163 | ||
164 | impl<'a> Drop for D<'a> { | |
165 | fn drop(&mut self) { | |
166 | unsafe { trails &= !(1 << self.trail); }; | |
167 | self.log.borrow_mut().push(self.uid); | |
168 | indent_println(self.trail, &format!("+-- Drop {}", self)); | |
169 | indent_println(::PREF_INDENT, ""); | |
170 | } | |
171 | } | |
172 | } |