run-pass tests.

includes regression tests discovered during bootstrapping and tests of
cyclic structure that currently pass and are expected to continue
passing under the dropck rule.

(Note that all the uses of `unsafe_destructor` are just placating the
simple analysis used for that feature, which will eventually go away
once we have put the dropck through its paces.)
This commit is contained in:
Felix S. Klock II 2015-01-05 13:26:29 +01:00
parent d6c158d262
commit 4459a438c2
8 changed files with 371 additions and 0 deletions

View File

@ -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.
use std::cell::Cell;
#[derive(Show)]
struct B<'a> {
a: [Cell<Option<&'a B<'a>>>; 2]
}
impl<'a> B<'a> {
fn new() -> B<'a> {
B { a: [Cell::new(None), Cell::new(None)] }
}
}
fn f() {
let (b1, b2, b3);
b1 = B::new();
b2 = B::new();
b3 = B::new();
b1.a[0].set(Some(&b2));
b1.a[1].set(Some(&b3));
b2.a[0].set(Some(&b2));
b2.a[1].set(Some(&b3));
b3.a[0].set(Some(&b1));
b3.a[1].set(Some(&b2));
}
fn main() {
f();
}

View File

@ -0,0 +1,51 @@
// 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.
// Check that a arena (TypedArena) can carry elements whose drop
// methods might access borrowed data, as long as the borrowed data
// has lifetime that strictly outlives the arena itself.
//
// Compare against compile-fail/dropck_tarena_unsound_drop.rs, which
// shows a similar setup, but restricts `f` so that the struct `C<'a>`
// is force-fed a lifetime equal to that of the borrowed arena.
#![allow(unstable)]
#![feature(unsafe_destructor)]
extern crate arena;
use arena::TypedArena;
trait HasId { fn count(&self) -> usize; }
struct CheckId<T:HasId> { v: T }
// In the code below, the impl of HasId for `&'a usize` does not
// actually access the borrowed data, but the point is that the
// interface to CheckId does not (and cannot) know that, and therefore
// when encountering the a value V of type CheckId<S>, we must
// conservatively force the type S to strictly outlive V.
#[unsafe_destructor]
impl<T:HasId> Drop for CheckId<T> {
fn drop(&mut self) {
assert!(self.v.count() > 0);
}
}
struct C<'a> { _v: CheckId<&'a usize>, }
impl<'a> HasId for &'a usize { fn count(&self) -> usize { 1 } }
fn f<'a, 'b>(_arena: &'a TypedArena<C<'b>>) {}
fn main() {
let arena: TypedArena<C> = TypedArena::new();
f(&arena);
}

View File

@ -0,0 +1,38 @@
// 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.
use std::cell::Cell;
struct C<'a> {
p: Cell<Option<&'a C<'a>>>,
}
impl<'a> C<'a> {
fn new() -> C<'a> { C { p: Cell::new(None) } }
}
fn f1() {
let (c1, c2) = (C::new(), C::new());
c1.p.set(Some(&c2));
c2.p.set(Some(&c1));
}
fn f2() {
let (c1, c2);
c1 = C::new();
c2 = C::new();
c1.p.set(Some(&c2));
c2.p.set(Some(&c1));
}
fn main() {
f1();
f2();
}

View File

@ -0,0 +1,53 @@
// Copyright 2012-2014 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 a regression test for something that only came up while
// attempting to bootstrap librustc with new destructor lifetime
// semantics.
use std::collections::HashMap;
use std::cell::RefCell;
// This version does not yet work (associated type issues)...
#[cfg(cannot_use_this_yet)]
fn foo<'a>(map: RefCell<HashMap<&'static str, &'a [u8]>>) {
let one = [1u];
assert_eq!(map.borrow().get("one"), Some(&one[]));
}
#[cfg(cannot_use_this_yet_either)]
// ... and this version does not work (the lifetime of `one` is
// supposed to match the lifetime `'a`) ...
fn foo<'a>(map: RefCell<HashMap<&'static str, &'a [u8]>>) {
let one = [1u];
assert_eq!(map.borrow().get("one"), Some(&one.as_slice()));
}
#[cfg(all(not(cannot_use_this_yet),not(cannot_use_this_yet_either)))]
fn foo<'a>(map: RefCell<HashMap<&'static str, &'a [u8]>>) {
// ...so instead we walk through the trivial slice and make sure
// it contains the element we expect.
for (i, &x) in map.borrow().get("one").unwrap().iter().enumerate() {
assert_eq!((i, x), (0, 1));
}
}
fn main() {
let zer = [0u8];
let one = [1u8];
let two = [2u8];
let mut map = HashMap::new();
map.insert("zero", &zer[]);
map.insert("one", &one[]);
map.insert("two", &two[]);
let map = RefCell::new(map);
foo(map);
}

View File

@ -0,0 +1,43 @@
// Copyright 2012-2014 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 a regression test for something that only came up while
// attempting to bootstrap libsyntax; it is adapted from
// `syntax::ext::tt::generic_extension`.
pub struct E<'a> {
pub f: &'a u8,
}
impl<'b> E<'b> {
pub fn m(&self) -> &'b u8 { self.f }
}
pub struct P<'c> {
pub g: &'c u8,
}
pub trait M {
fn n(&self) -> u8;
}
impl<'d> M for P<'d> {
fn n(&self) -> u8 { *self.g }
}
fn extension<'e>(x: &'e E<'e>) -> Box<M+'e> {
loop {
let p = P { g: x.m() };
return Box::new(p) as Box<M+'e>;
}
}
fn main() {
let w = E { f: &10u8 };
let o = extension(&w);
assert_eq!(o.n(), 10u8);
}

View File

@ -0,0 +1,42 @@
// Copyright 2014 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.
// Uncovered during work on new scoping rules for safe destructors
// as an important use case to support properly.
pub struct E<'a> {
pub f: &'a u8,
}
impl<'b> E<'b> {
pub fn m(&self) -> &'b u8 { self.f }
}
pub struct P<'c> {
pub g: &'c u8,
}
pub trait M {
fn n(&self) -> u8;
}
impl<'d> M for P<'d> {
fn n(&self) -> u8 { *self.g }
}
fn extension<'e>(x: &'e E<'e>) -> Box<M+'e> {
loop {
let p = P { g: x.m() };
return Box::new(p) as Box<M+'e>;
}
}
fn main() {
let w = E { f: &10u8 };
let o = extension(&w);
assert_eq!(o.n(), 10u8);
}

View File

@ -0,0 +1,47 @@
// 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.
use std::cell::Cell;
#[derive(Show)]
struct C<'a> {
v: Vec<Cell<Option<&'a C<'a>>>>,
}
impl<'a> C<'a> {
fn new() -> C<'a> {
C { v: Vec::new() }
}
}
fn f() {
let (mut c1, mut c2, mut c3);
c1 = C::new();
c2 = C::new();
c3 = C::new();
c1.v.push(Cell::new(None));
c1.v.push(Cell::new(None));
c2.v.push(Cell::new(None));
c2.v.push(Cell::new(None));
c3.v.push(Cell::new(None));
c3.v.push(Cell::new(None));
c1.v[0].set(Some(&c2));
c1.v[1].set(Some(&c3));
c2.v[0].set(Some(&c2));
c2.v[1].set(Some(&c3));
c3.v[0].set(Some(&c1));
c3.v[1].set(Some(&c2));
}
fn main() {
f();
}

View File

@ -0,0 +1,58 @@
// 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.
use std::cell::Cell;
#[derive(Show)]
struct Refs<'a> {
v: Vec<Cell<Option<&'a C<'a>>>>,
}
#[derive(Show)]
struct C<'a> {
refs: Refs<'a>,
}
impl<'a> Refs<'a> {
fn new() -> Refs<'a> {
Refs { v: Vec::new() }
}
}
impl<'a> C<'a> {
fn new() -> C<'a> {
C { refs: Refs::new() }
}
}
fn f() {
let (mut c1, mut c2, mut c3);
c1 = C::new();
c2 = C::new();
c3 = C::new();
c1.refs.v.push(Cell::new(None));
c1.refs.v.push(Cell::new(None));
c2.refs.v.push(Cell::new(None));
c2.refs.v.push(Cell::new(None));
c3.refs.v.push(Cell::new(None));
c3.refs.v.push(Cell::new(None));
c1.refs.v[0].set(Some(&c2));
c1.refs.v[1].set(Some(&c3));
c2.refs.v[0].set(Some(&c2));
c2.refs.v[1].set(Some(&c3));
c3.refs.v[0].set(Some(&c1));
c3.refs.v[1].set(Some(&c2));
}
fn main() {
f();
}