about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/test/run-pass/arr_cycle.rs39
-rw-r--r--src/test/run-pass/dropck_tarena_sound_drop.rs51
-rw-r--r--src/test/run-pass/nondrop-cycle.rs38
-rw-r--r--src/test/run-pass/regions-refcell.rs53
-rw-r--r--src/test/run-pass/regions-trait-object-1.rs43
-rw-r--r--src/test/run-pass/trait-object-with-lifetime-bound.rs42
-rw-r--r--src/test/run-pass/vec_cycle.rs47
-rw-r--r--src/test/run-pass/vec_cycle_wrapped.rs58
8 files changed, 371 insertions, 0 deletions
diff --git a/src/test/run-pass/arr_cycle.rs b/src/test/run-pass/arr_cycle.rs
new file mode 100644
index 00000000000..80434f36b42
--- /dev/null
+++ b/src/test/run-pass/arr_cycle.rs
@@ -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();
+}
diff --git a/src/test/run-pass/dropck_tarena_sound_drop.rs b/src/test/run-pass/dropck_tarena_sound_drop.rs
new file mode 100644
index 00000000000..ad71f725864
--- /dev/null
+++ b/src/test/run-pass/dropck_tarena_sound_drop.rs
@@ -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);
+}
diff --git a/src/test/run-pass/nondrop-cycle.rs b/src/test/run-pass/nondrop-cycle.rs
new file mode 100644
index 00000000000..bbce9a8f4a6
--- /dev/null
+++ b/src/test/run-pass/nondrop-cycle.rs
@@ -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();
+}
diff --git a/src/test/run-pass/regions-refcell.rs b/src/test/run-pass/regions-refcell.rs
new file mode 100644
index 00000000000..019db2a977e
--- /dev/null
+++ b/src/test/run-pass/regions-refcell.rs
@@ -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);
+}
diff --git a/src/test/run-pass/regions-trait-object-1.rs b/src/test/run-pass/regions-trait-object-1.rs
new file mode 100644
index 00000000000..eb3bec77326
--- /dev/null
+++ b/src/test/run-pass/regions-trait-object-1.rs
@@ -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);
+}
diff --git a/src/test/run-pass/trait-object-with-lifetime-bound.rs b/src/test/run-pass/trait-object-with-lifetime-bound.rs
new file mode 100644
index 00000000000..4e481910aa9
--- /dev/null
+++ b/src/test/run-pass/trait-object-with-lifetime-bound.rs
@@ -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);
+}
diff --git a/src/test/run-pass/vec_cycle.rs b/src/test/run-pass/vec_cycle.rs
new file mode 100644
index 00000000000..65522bd95df
--- /dev/null
+++ b/src/test/run-pass/vec_cycle.rs
@@ -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();
+}
diff --git a/src/test/run-pass/vec_cycle_wrapped.rs b/src/test/run-pass/vec_cycle_wrapped.rs
new file mode 100644
index 00000000000..f179df90b34
--- /dev/null
+++ b/src/test/run-pass/vec_cycle_wrapped.rs
@@ -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();
+}