Skip to content

Commit c4216a5

Browse files
committed
Test cases for Issue 23338.
We ignore pretty for the params-outlive-temps-of-body test because the way its comments are formatted exercises a known bug in the pretty printer.
1 parent 05b8a10 commit c4216a5

File tree

3 files changed

+246
-0
lines changed

3 files changed

+246
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
// This is just checking that we still reject code where temp values
12+
// are borrowing values for longer than they will be around.
13+
//
14+
// Compare to run-pass/issue-23338-params-outlive-temps-of-body.rs
15+
16+
use std::cell::RefCell;
17+
18+
fn foo(x: RefCell<String>) -> String {
19+
let y = x;
20+
y.borrow().clone() //~ ERROR `y` does not live long enough
21+
}
22+
23+
fn foo2(x: RefCell<String>) -> String {
24+
let ret = {
25+
let y = x;
26+
y.borrow().clone() //~ ERROR `y` does not live long enough
27+
};
28+
ret
29+
}
30+
31+
fn main() {
32+
let r = RefCell::new(format!("data"));
33+
assert_eq!(foo(r), "data");
34+
let r = RefCell::new(format!("data"));
35+
assert_eq!(foo2(r), "data");
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
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(&format!("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(&format!("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(&format!("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(&format!("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+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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+
// This is largely checking that we now accept code where temp values
12+
// are borrowing from the input parameters (the `foo` case below).
13+
//
14+
// Compare to run-pass/issue-23338-params-outlive-temps-of-body.rs
15+
//
16+
// (The `foo2` case is just for parity with the above test, which
17+
// shows what happens when you move the `y`-binding to the inside of
18+
// the inner block.)
19+
20+
use std::cell::RefCell;
21+
22+
fn foo(x: RefCell<String>) -> String {
23+
x.borrow().clone()
24+
}
25+
26+
fn foo2(x: RefCell<String>) -> String {
27+
let y = x;
28+
let ret = {
29+
y.borrow().clone()
30+
};
31+
ret
32+
}
33+
34+
pub fn main() {
35+
let r = RefCell::new(format!("data"));
36+
assert_eq!(foo(r), "data");
37+
let r = RefCell::new(format!("data"));
38+
assert_eq!(foo2(r), "data");
39+
}

0 commit comments

Comments
 (0)