]> git.proxmox.com Git - rustc.git/blame - src/test/run-pass/issue-23338-ensure-param-drop-order.rs
New upstream version 1.14.0+dfsg1
[rustc.git] / src / test / run-pass / issue-23338-ensure-param-drop-order.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
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
16use std::cell::RefCell;
17
18use self::d::D;
19
20pub 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
59fn 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.
68fn 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
83const PREF_INDENT: u32 = 16;
84
85pub 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}