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.
This commit is contained in:
parent
05b8a106e4
commit
c4216a50bd
@ -0,0 +1,36 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// This is just checking that we still reject code where temp values
|
||||
// are borrowing values for longer than they will be around.
|
||||
//
|
||||
// Compare to run-pass/issue-23338-params-outlive-temps-of-body.rs
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
||||
fn foo(x: RefCell<String>) -> String {
|
||||
let y = x;
|
||||
y.borrow().clone() //~ ERROR `y` does not live long enough
|
||||
}
|
||||
|
||||
fn foo2(x: RefCell<String>) -> String {
|
||||
let ret = {
|
||||
let y = x;
|
||||
y.borrow().clone() //~ ERROR `y` does not live long enough
|
||||
};
|
||||
ret
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let r = RefCell::new(format!("data"));
|
||||
assert_eq!(foo(r), "data");
|
||||
let r = RefCell::new(format!("data"));
|
||||
assert_eq!(foo2(r), "data");
|
||||
}
|
171
src/test/run-pass/issue-23338-ensure-param-drop-order.rs
Normal file
171
src/test/run-pass/issue-23338-ensure-param-drop-order.rs
Normal file
@ -0,0 +1,171 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-pretty : (#23623) problems when ending with // comments
|
||||
|
||||
// This test is ensuring that parameters are indeed dropped after
|
||||
// temporaries in a fn body.
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
||||
use self::d::D;
|
||||
|
||||
pub fn main() {
|
||||
let log = RefCell::new(vec![]);
|
||||
d::println(&format!("created empty log"));
|
||||
test(&log);
|
||||
|
||||
assert_eq!(&log.borrow()[..],
|
||||
[
|
||||
// created empty log
|
||||
// +-- Make D(da_0, 0)
|
||||
// | +-- Make D(de_1, 1)
|
||||
// | | calling foo
|
||||
// | | entered foo
|
||||
// | | +-- Make D(de_2, 2)
|
||||
// | | | +-- Make D(da_1, 3)
|
||||
// | | | | +-- Make D(de_3, 4)
|
||||
// | | | | | +-- Make D(de_4, 5)
|
||||
3, // | | | +-- Drop D(da_1, 3)
|
||||
// | | | | |
|
||||
4, // | | | +-- Drop D(de_3, 4)
|
||||
// | | | |
|
||||
// | | | | eval tail of foo
|
||||
// | | | +-- Make D(de_5, 6)
|
||||
// | | | | +-- Make D(de_6, 7)
|
||||
6, // | | | +-- Drop D(de_5, 6)
|
||||
// | | | | |
|
||||
5, // | | | | +-- Drop D(de_4, 5)
|
||||
// | | | |
|
||||
2, // | | +-- Drop D(de_2, 2)
|
||||
// | | |
|
||||
1, // | +-- Drop D(de_1, 1)
|
||||
// | |
|
||||
0, // +-- Drop D(da_0, 0)
|
||||
// |
|
||||
// | result D(de_6, 7)
|
||||
7 // +-- Drop D(de_6, 7)
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
fn test<'a>(log: d::Log<'a>) {
|
||||
let da = D::new("da", 0, log);
|
||||
let de = D::new("de", 1, log);
|
||||
d::println(&format!("calling foo"));
|
||||
let result = foo(da, de);
|
||||
d::println(&format!("result {}", result));
|
||||
}
|
||||
|
||||
fn foo<'a>(da0: D<'a>, de1: D<'a>) -> D<'a> {
|
||||
d::println(&format!("entered foo"));
|
||||
let de2 = de1.incr(); // creates D(de_2, 2)
|
||||
let de4 = {
|
||||
let _da1 = da0.incr(); // creates D(da_1, 3)
|
||||
de2.incr().incr() // creates D(de_3, 4) and D(de_4, 5)
|
||||
};
|
||||
d::println(&format!("eval tail of foo"));
|
||||
de4.incr().incr() // creates D(de_5, 6) and D(de_6, 7)
|
||||
}
|
||||
|
||||
// This module provides simultaneous printouts of the dynamic extents
|
||||
// of all of the D values, in addition to logging the order that each
|
||||
// is dropped.
|
||||
|
||||
const PREF_INDENT: u32 = 16;
|
||||
|
||||
pub mod d {
|
||||
#![allow(unused_parens)]
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
use std::cell::RefCell;
|
||||
|
||||
static mut counter: u32 = 0;
|
||||
static mut trails: u64 = 0;
|
||||
|
||||
pub type Log<'a> = &'a RefCell<Vec<u32>>;
|
||||
|
||||
pub fn current_width() -> u32 {
|
||||
unsafe { max_width() - trails.leading_zeros() }
|
||||
}
|
||||
|
||||
pub fn max_width() -> u32 {
|
||||
unsafe {
|
||||
(mem::size_of_val(&trails)*8) as u32
|
||||
}
|
||||
}
|
||||
|
||||
pub fn indent_println(my_trails: u32, s: &str) {
|
||||
let mut indent: String = String::new();
|
||||
for i in 0..my_trails {
|
||||
unsafe {
|
||||
if trails & (1 << i) != 0 {
|
||||
indent = indent + "| ";
|
||||
} else {
|
||||
indent = indent + " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("{}{}", indent, s);
|
||||
}
|
||||
|
||||
pub fn println(s: &str) {
|
||||
indent_println(super::PREF_INDENT, s);
|
||||
}
|
||||
|
||||
fn first_avail() -> u32 {
|
||||
unsafe {
|
||||
for i in 0..64 {
|
||||
if trails & (1 << i) == 0 {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
panic!("exhausted trails");
|
||||
}
|
||||
|
||||
pub struct D<'a> {
|
||||
name: &'static str, i: u32, uid: u32, trail: u32, log: Log<'a>
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for D<'a> {
|
||||
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(w, "D({}_{}, {})", self.name, self.i, self.uid)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> D<'a> {
|
||||
pub fn new(name: &'static str, i: u32, log: Log<'a>) -> D<'a> {
|
||||
unsafe {
|
||||
let trail = first_avail();
|
||||
let ctr = counter;
|
||||
counter += 1;
|
||||
trails |= (1 << trail);
|
||||
let ret = D {
|
||||
name: name, i: i, log: log, uid: ctr, trail: trail
|
||||
};
|
||||
indent_println(trail, &format!("+-- Make {}", ret));
|
||||
ret
|
||||
}
|
||||
}
|
||||
pub fn incr(&self) -> D<'a> {
|
||||
D::new(self.name, self.i + 1, self.log)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for D<'a> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { trails &= !(1 << self.trail); };
|
||||
self.log.borrow_mut().push(self.uid);
|
||||
indent_println(self.trail, &format!("+-- Drop {}", self));
|
||||
indent_println(::PREF_INDENT, "");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// This is largely checking that we now accept code where temp values
|
||||
// are borrowing from the input parameters (the `foo` case below).
|
||||
//
|
||||
// Compare to run-pass/issue-23338-params-outlive-temps-of-body.rs
|
||||
//
|
||||
// (The `foo2` case is just for parity with the above test, which
|
||||
// shows what happens when you move the `y`-binding to the inside of
|
||||
// the inner block.)
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
||||
fn foo(x: RefCell<String>) -> String {
|
||||
x.borrow().clone()
|
||||
}
|
||||
|
||||
fn foo2(x: RefCell<String>) -> String {
|
||||
let y = x;
|
||||
let ret = {
|
||||
y.borrow().clone()
|
||||
};
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let r = RefCell::new(format!("data"));
|
||||
assert_eq!(foo(r), "data");
|
||||
let r = RefCell::new(format!("data"));
|
||||
assert_eq!(foo2(r), "data");
|
||||
}
|
Loading…
Reference in New Issue
Block a user