diff --git a/src/test/run-pass/arr_cycle.rs b/src/test/run-pass/arr_cycle.rs new file mode 100644 index 000000000000..80434f36b42d --- /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 or the MIT license +// , 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>>; 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 000000000000..ad71f725864f --- /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 or the MIT license +// , 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 { 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, we must +// conservatively force the type S to strictly outlive V. +#[unsafe_destructor] +impl Drop for CheckId { + 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>) {} + +fn main() { + let arena: TypedArena = 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 000000000000..bbce9a8f4a6a --- /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 or the MIT license +// , 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>>, +} + +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 000000000000..019db2a977e4 --- /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 or the MIT license +// , 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>) { + 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>) { + 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>) { + // ...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 000000000000..eb3bec773266 --- /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 or the MIT license +// , 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 { + loop { + let p = P { g: x.m() }; + return Box::new(p) as Box; + } +} + +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 000000000000..4e481910aa98 --- /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 or the MIT license +// , 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 { + loop { + let p = P { g: x.m() }; + return Box::new(p) as Box; + } +} + +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 000000000000..65522bd95df7 --- /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 or the MIT license +// , 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>>>, +} + +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 000000000000..f179df90b34c --- /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 or the MIT license +// , 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>>>, +} + +#[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(); +}