mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
cleaned up some tests
This commit is contained in:
+9
-5
@@ -1,15 +1,19 @@
|
||||
// Test that the borrow checker prevents pointers to temporaries
|
||||
// with statement lifetimes from escaping.
|
||||
//! Test that the borrow checker prevents pointers to temporaries
|
||||
//! with statement lifetimes from escaping.
|
||||
|
||||
use std::ops::Drop;
|
||||
|
||||
static mut FLAGS: u64 = 0;
|
||||
|
||||
struct StackBox<T> { f: T }
|
||||
struct AddFlags { bits: u64 }
|
||||
struct StackBox<T> {
|
||||
f: T,
|
||||
}
|
||||
struct AddFlags {
|
||||
bits: u64,
|
||||
}
|
||||
|
||||
fn AddFlags(bits: u64) -> AddFlags {
|
||||
AddFlags { bits: bits }
|
||||
AddFlags { bits }
|
||||
}
|
||||
|
||||
fn arg(x: &AddFlags) -> &AddFlags {
|
||||
+7
-7
@@ -1,5 +1,5 @@
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/cleanup-rvalue-scopes-cf.rs:26:19
|
||||
--> $DIR/rvalue-borrow-scope-error.rs:30:19
|
||||
|
|
||||
LL | let x1 = arg(&AddFlags(1));
|
||||
| ^^^^^^^^^^^ - temporary value is freed at the end of this statement
|
||||
@@ -16,7 +16,7 @@ LL ~ let x1 = arg(&binding);
|
||||
|
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/cleanup-rvalue-scopes-cf.rs:27:14
|
||||
--> $DIR/rvalue-borrow-scope-error.rs:31:14
|
||||
|
|
||||
LL | let x2 = AddFlags(1).get();
|
||||
| ^^^^^^^^^^^ - temporary value is freed at the end of this statement
|
||||
@@ -33,7 +33,7 @@ LL ~ let x2 = binding.get();
|
||||
|
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/cleanup-rvalue-scopes-cf.rs:28:21
|
||||
--> $DIR/rvalue-borrow-scope-error.rs:32:21
|
||||
|
|
||||
LL | let x3 = &*arg(&AddFlags(1));
|
||||
| ^^^^^^^^^^^ - temporary value is freed at the end of this statement
|
||||
@@ -50,7 +50,7 @@ LL ~ let x3 = &*arg(&binding);
|
||||
|
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/cleanup-rvalue-scopes-cf.rs:29:24
|
||||
--> $DIR/rvalue-borrow-scope-error.rs:33:24
|
||||
|
|
||||
LL | let ref x4 = *arg(&AddFlags(1));
|
||||
| ^^^^^^^^^^^ - temporary value is freed at the end of this statement
|
||||
@@ -67,7 +67,7 @@ LL ~ let ref x4 = *arg(&binding);
|
||||
|
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/cleanup-rvalue-scopes-cf.rs:30:24
|
||||
--> $DIR/rvalue-borrow-scope-error.rs:34:24
|
||||
|
|
||||
LL | let &ref x5 = arg(&AddFlags(1));
|
||||
| ^^^^^^^^^^^ - temporary value is freed at the end of this statement
|
||||
@@ -84,7 +84,7 @@ LL ~ let &ref x5 = arg(&binding);
|
||||
|
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/cleanup-rvalue-scopes-cf.rs:31:14
|
||||
--> $DIR/rvalue-borrow-scope-error.rs:35:14
|
||||
|
|
||||
LL | let x6 = AddFlags(1).get();
|
||||
| ^^^^^^^^^^^ - temporary value is freed at the end of this statement
|
||||
@@ -101,7 +101,7 @@ LL ~ let x6 = binding.get();
|
||||
|
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/cleanup-rvalue-scopes-cf.rs:32:44
|
||||
--> $DIR/rvalue-borrow-scope-error.rs:36:44
|
||||
|
|
||||
LL | let StackBox { f: x7 } = StackBox { f: AddFlags(1).get() };
|
||||
| ^^^^^^^^^^^ - temporary value is freed at the end of this statement
|
||||
@@ -1,128 +0,0 @@
|
||||
//@ run-pass
|
||||
#![allow(unused_braces)]
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(unused_variables)]
|
||||
// Test that destructors for rvalue temporaries run either at end of
|
||||
// statement or end of block, as appropriate given the temporary
|
||||
// lifetime rules.
|
||||
|
||||
#![feature(box_patterns)]
|
||||
|
||||
static mut FLAGS: u64 = 0;
|
||||
|
||||
struct Box<T> { f: T }
|
||||
struct AddFlags { bits: u64 }
|
||||
|
||||
fn AddFlags(bits: u64) -> AddFlags {
|
||||
AddFlags { bits: bits }
|
||||
}
|
||||
|
||||
fn arg(exp: u64, _x: &AddFlags) {
|
||||
check_flags(exp);
|
||||
}
|
||||
|
||||
fn pass<T>(v: T) -> T {
|
||||
v
|
||||
}
|
||||
|
||||
fn check_flags(exp: u64) {
|
||||
unsafe {
|
||||
let x = FLAGS;
|
||||
FLAGS = 0;
|
||||
println!("flags {}, expected {}", x, exp);
|
||||
assert_eq!(x, exp);
|
||||
}
|
||||
}
|
||||
|
||||
impl AddFlags {
|
||||
fn check_flags<'a>(&'a self, exp: u64) -> &'a AddFlags {
|
||||
check_flags(exp);
|
||||
self
|
||||
}
|
||||
|
||||
fn bits(&self) -> u64 {
|
||||
self.bits
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for AddFlags {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
FLAGS = FLAGS + self.bits;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! end_of_block {
|
||||
($pat:pat, $expr:expr) => (
|
||||
{
|
||||
println!("end_of_block({})", stringify!({let $pat = $expr;}));
|
||||
|
||||
{
|
||||
// Destructor here does not run until exit from the block.
|
||||
let $pat = $expr;
|
||||
check_flags(0);
|
||||
}
|
||||
check_flags(1);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
macro_rules! end_of_stmt {
|
||||
($pat:pat, $expr:expr) => (
|
||||
{
|
||||
println!("end_of_stmt({})", stringify!($expr));
|
||||
|
||||
{
|
||||
// Destructor here run after `let` statement
|
||||
// terminates.
|
||||
let $pat = $expr;
|
||||
check_flags(1);
|
||||
}
|
||||
|
||||
check_flags(0);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
|
||||
// In all these cases, we trip over the rules designed to cover
|
||||
// the case where we are taking addr of rvalue and storing that
|
||||
// addr into a stack slot, either via `let ref` or via a `&` in
|
||||
// the initializer.
|
||||
|
||||
end_of_block!(_x, AddFlags(1));
|
||||
end_of_block!(_x, &AddFlags(1));
|
||||
end_of_block!(_x, & &AddFlags(1));
|
||||
end_of_block!(_x, Box { f: AddFlags(1) });
|
||||
end_of_block!(_x, Box { f: &AddFlags(1) });
|
||||
end_of_block!(_x, Box { f: &AddFlags(1) });
|
||||
end_of_block!(_x, pass(AddFlags(1)));
|
||||
end_of_block!(ref _x, AddFlags(1));
|
||||
end_of_block!(AddFlags { bits: ref _x }, AddFlags(1));
|
||||
end_of_block!(&AddFlags { bits }, &AddFlags(1));
|
||||
end_of_block!((_, ref _y), (AddFlags(1), 22));
|
||||
end_of_block!(box ref _x, std::boxed::Box::new(AddFlags(1)));
|
||||
end_of_block!(box _x, std::boxed::Box::new(AddFlags(1)));
|
||||
end_of_block!(_, { { check_flags(0); &AddFlags(1) } });
|
||||
end_of_block!(_, &((Box { f: AddFlags(1) }).f));
|
||||
end_of_block!(_, &(([AddFlags(1)])[0]));
|
||||
|
||||
// LHS does not create a ref binding, so temporary lives as long
|
||||
// as statement, and we do not move the AddFlags out:
|
||||
end_of_stmt!(_, AddFlags(1));
|
||||
end_of_stmt!((_, _), (AddFlags(1), 22));
|
||||
|
||||
// `&` operator appears inside an arg to a function,
|
||||
// so it is not prolonged:
|
||||
end_of_stmt!(ref _x, arg(0, &AddFlags(1)));
|
||||
|
||||
// autoref occurs inside receiver, so temp lifetime is not
|
||||
// prolonged:
|
||||
end_of_stmt!(ref _x, AddFlags(1).check_flags(0).bits());
|
||||
|
||||
// No reference is created on LHS, thus RHS is moved into
|
||||
// a temporary that lives just as long as the statement.
|
||||
end_of_stmt!(AddFlags { bits }, AddFlags(1));
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
//@ run-pass
|
||||
|
||||
#![allow(dead_code)]
|
||||
// If we use GEPi rather than GEP_tup_like when
|
||||
// storing closure data (as we used to do), the u64 would
|
||||
// overwrite the u16.
|
||||
|
||||
struct Pair<A,B> {
|
||||
a: A, b: B
|
||||
}
|
||||
|
||||
struct Invoker<A> {
|
||||
a: A,
|
||||
b: u16,
|
||||
}
|
||||
|
||||
trait Invokable<A> {
|
||||
fn f(&self) -> (A, u16);
|
||||
}
|
||||
|
||||
impl<A:Clone> Invokable<A> for Invoker<A> {
|
||||
fn f(&self) -> (A, u16) {
|
||||
(self.a.clone(), self.b)
|
||||
}
|
||||
}
|
||||
|
||||
fn f<A:Clone + 'static>(a: A, b: u16) -> Box<dyn Invokable<A>+'static> {
|
||||
Box::new(Invoker {
|
||||
a: a,
|
||||
b: b,
|
||||
}) as Box<dyn Invokable<A>+'static>
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let (a, b) = f(22_u64, 44u16).f();
|
||||
println!("a={} b={}", a, b);
|
||||
assert_eq!(a, 22u64);
|
||||
assert_eq!(b, 44u16);
|
||||
}
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
// This test checks the output format without the intermediate json representation
|
||||
//! This test checks the output format without the intermediate json representation
|
||||
|
||||
//@ compile-flags: --error-format=human
|
||||
|
||||
pub fn main() {
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
error[E0384]: cannot assign twice to immutable variable `x`
|
||||
--> $DIR/command-line-diagnostics.rs:6:5
|
||||
--> $DIR/command-line-error-format-human.rs:7:5
|
||||
|
|
||||
LL | let x = 42;
|
||||
| - first assignment to `x`
|
||||
+5
-4
@@ -1,10 +1,9 @@
|
||||
//@ run-pass
|
||||
// Test that cleanups for the RHS of shortcircuiting operators work.
|
||||
//! Test that cleanups for the RHS of shortcircuiting operators work.
|
||||
|
||||
//@ run-pass
|
||||
|
||||
#![allow(deref_nullptr)]
|
||||
|
||||
|
||||
use std::env;
|
||||
|
||||
pub fn main() {
|
||||
@@ -18,6 +17,8 @@ pub fn main() {
|
||||
|
||||
if args.len() >= 2 && args[1] == "signal" {
|
||||
// Raise a segfault.
|
||||
unsafe { *std::ptr::null_mut::<isize>() = 0; }
|
||||
unsafe {
|
||||
*std::ptr::null_mut::<isize>() = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
//! Test that destructors for temporaries run either at end of
|
||||
//! statement or end of block as appropriate.
|
||||
|
||||
//@ run-pass
|
||||
|
||||
#![feature(box_patterns)]
|
||||
|
||||
static mut FLAGS: u64 = 0;
|
||||
|
||||
struct Box<T> {
|
||||
f: T,
|
||||
}
|
||||
|
||||
struct AddFlags {
|
||||
bits: u64,
|
||||
}
|
||||
|
||||
fn add_flags(bits: u64) -> AddFlags {
|
||||
AddFlags { bits }
|
||||
}
|
||||
|
||||
fn arg(expected: u64, _x: &AddFlags) {
|
||||
check_flags(expected);
|
||||
}
|
||||
|
||||
fn pass<T>(v: T) -> T {
|
||||
v
|
||||
}
|
||||
|
||||
fn check_flags(expected: u64) {
|
||||
unsafe {
|
||||
let actual = FLAGS;
|
||||
FLAGS = 0;
|
||||
assert_eq!(actual, expected, "flags {}, expected {}", actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
impl AddFlags {
|
||||
fn check_flags(&self, expected: u64) -> &AddFlags {
|
||||
check_flags(expected);
|
||||
self
|
||||
}
|
||||
|
||||
fn bits(&self) -> u64 {
|
||||
self.bits
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for AddFlags {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
FLAGS += self.bits;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! end_of_block {
|
||||
($pat:pat, $expr:expr) => {{
|
||||
{
|
||||
let $pat = $expr;
|
||||
check_flags(0);
|
||||
}
|
||||
check_flags(1);
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! end_of_stmt {
|
||||
($pat:pat, $expr:expr) => {{
|
||||
{
|
||||
let $pat = $expr;
|
||||
check_flags(1);
|
||||
}
|
||||
check_flags(0);
|
||||
}};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
end_of_block!(_x, add_flags(1));
|
||||
end_of_block!(_x, &add_flags(1));
|
||||
end_of_block!(_x, &&add_flags(1));
|
||||
end_of_block!(_x, Box { f: add_flags(1) });
|
||||
end_of_block!(_x, Box { f: &add_flags(1) });
|
||||
end_of_block!(_x, pass(add_flags(1)));
|
||||
end_of_block!(ref _x, add_flags(1));
|
||||
end_of_block!(AddFlags { bits: ref _x }, add_flags(1));
|
||||
end_of_block!(&AddFlags { bits: _ }, &add_flags(1));
|
||||
end_of_block!((_, ref _y), (add_flags(1), 22));
|
||||
end_of_block!(box ref _x, std::boxed::Box::new(add_flags(1)));
|
||||
end_of_block!(box _x, std::boxed::Box::new(add_flags(1)));
|
||||
end_of_block!(_, {
|
||||
{
|
||||
check_flags(0);
|
||||
&add_flags(1)
|
||||
}
|
||||
});
|
||||
end_of_block!(_, &((Box { f: add_flags(1) }).f));
|
||||
end_of_block!(_, &(([add_flags(1)])[0]));
|
||||
|
||||
end_of_stmt!(_, add_flags(1));
|
||||
end_of_stmt!((_, _), (add_flags(1), 22));
|
||||
end_of_stmt!(ref _x, arg(0, &add_flags(1)));
|
||||
end_of_stmt!(ref _x, add_flags(1).check_flags(0).bits());
|
||||
end_of_stmt!(AddFlags { bits: _ }, add_flags(1));
|
||||
}
|
||||
+7
-3
@@ -25,16 +25,20 @@
|
||||
use std::thread;
|
||||
|
||||
enum Conzabble {
|
||||
Bickwick(Foo)
|
||||
Bickwick(Foo),
|
||||
}
|
||||
|
||||
struct Foo { field: Box<usize> }
|
||||
struct Foo {
|
||||
field: Box<usize>,
|
||||
}
|
||||
|
||||
fn do_it(x: &[usize]) -> Foo {
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn get_bar(x: usize) -> Vec<usize> { vec![x * 2] }
|
||||
fn get_bar(x: usize) -> Vec<usize> {
|
||||
vec![x * 2]
|
||||
}
|
||||
|
||||
pub fn fails() {
|
||||
let x = 2;
|
||||
Reference in New Issue
Block a user