Skip to content

Commit 0e4faaf

Browse files
committed
---
yaml --- r: 180069 b: refs/heads/auto c: c1cda07 h: refs/heads/master i: 180067: f99d055 v: v3
1 parent d1dfdba commit 0e4faaf

9 files changed

+664
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1010
refs/tags/release-0.3.1: 495bae036dfe5ec6ceafd3312b4dca48741e845b
1111
refs/tags/release-0.4: e828ea2080499553b97dfe33b3f4d472b4562ad7
1212
refs/tags/release-0.5: 7e3bcfbf21278251ee936ad53e92e9b719702d73
13-
refs/heads/auto: 4459a438c282e953bb35afb9e5829fcaeca91bad
13+
refs/heads/auto: c1cda0793e4e7b92a73cc13ee6e4a6b14a1b633f
1414
refs/heads/servo: af82457af293e2a842ba6b7759b70288da276167
1515
refs/tags/release-0.6: b4ebcfa1812664df5e142f0134a5faea3918544c
1616
refs/tags/0.1: b19db808c2793fe2976759b85a355c3ad8c8b336
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Tests the new destructor semantics.
12+
13+
use std::cell::RefCell;
14+
15+
fn main() {
16+
let b = {
17+
let a = Box::new(RefCell::new(4i8));
18+
*a.borrow() + 1i8 //~ ERROR `*a` does not live long enough
19+
};
20+
println!("{}", b);
21+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Reject mixing cyclic structure and Drop when using fixed length
12+
// arrays.
13+
//
14+
// (Compare against compile-fail/dropck_vec_cycle_checked.rs)
15+
16+
#![feature(unsafe_destructor)]
17+
18+
use std::cell::Cell;
19+
use id::Id;
20+
21+
mod s {
22+
#![allow(unstable)]
23+
use std::sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering};
24+
25+
static S_COUNT: AtomicUint = ATOMIC_UINT_INIT;
26+
27+
pub fn next_count() -> usize {
28+
S_COUNT.fetch_add(1, Ordering::SeqCst) + 1
29+
}
30+
}
31+
32+
mod id {
33+
use s;
34+
#[derive(Debug)]
35+
pub struct Id {
36+
orig_count: usize,
37+
count: usize,
38+
}
39+
40+
impl Id {
41+
pub fn new() -> Id {
42+
let c = s::next_count();
43+
println!("building Id {}", c);
44+
Id { orig_count: c, count: c }
45+
}
46+
pub fn count(&self) -> usize {
47+
println!("Id::count on {} returns {}", self.orig_count, self.count);
48+
self.count
49+
}
50+
}
51+
52+
impl Drop for Id {
53+
fn drop(&mut self) {
54+
println!("dropping Id {}", self.count);
55+
self.count = 0;
56+
}
57+
}
58+
}
59+
60+
trait HasId {
61+
fn count(&self) -> usize;
62+
}
63+
64+
#[derive(Debug)]
65+
struct CheckId<T:HasId> {
66+
v: T
67+
}
68+
69+
#[allow(non_snake_case)]
70+
fn CheckId<T:HasId>(t: T) -> CheckId<T> { CheckId{ v: t } }
71+
72+
#[unsafe_destructor]
73+
impl<T:HasId> Drop for CheckId<T> {
74+
fn drop(&mut self) {
75+
assert!(self.v.count() > 0);
76+
}
77+
}
78+
79+
#[derive(Debug)]
80+
struct B<'a> {
81+
id: Id,
82+
a: [CheckId<Cell<Option<&'a B<'a>>>>; 2]
83+
}
84+
85+
impl<'a> HasId for Cell<Option<&'a B<'a>>> {
86+
fn count(&self) -> usize {
87+
match self.get() {
88+
None => 1,
89+
Some(b) => b.id.count(),
90+
}
91+
}
92+
}
93+
94+
impl<'a> B<'a> {
95+
fn new() -> B<'a> {
96+
B { id: Id::new(), a: [CheckId(Cell::new(None)), CheckId(Cell::new(None))] }
97+
}
98+
}
99+
100+
fn f() {
101+
let (b1, b2, b3);
102+
b1 = B::new();
103+
b2 = B::new();
104+
b3 = B::new();
105+
b1.a[0].v.set(Some(&b2)); //~ ERROR `b2` does not live long enough
106+
b1.a[1].v.set(Some(&b3)); //~ ERROR `b3` does not live long enough
107+
b2.a[0].v.set(Some(&b2)); //~ ERROR `b2` does not live long enough
108+
b2.a[1].v.set(Some(&b3)); //~ ERROR `b3` does not live long enough
109+
b3.a[0].v.set(Some(&b1)); //~ ERROR `b1` does not live long enough
110+
b3.a[1].v.set(Some(&b2)); //~ ERROR `b2` does not live long enough
111+
}
112+
113+
fn main() {
114+
f();
115+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// A simple example of an unsound mixing of cyclic structure and Drop.
12+
//
13+
// Each `D` has a name and an optional reference to another `D`
14+
// sibling, but also implements a drop method that prints out its own
15+
// name as well as the name of its sibling.
16+
//
17+
// By setting up a cyclic structure, the drop code cannot possibly
18+
// work. Therefore this code must be rejected.
19+
//
20+
// (As it turns out, essentially any attempt to install a sibling here
21+
// will be rejected, regardless of whether it forms a cyclic
22+
// structure or not. This is because the use of the same lifetime
23+
// `'a` in `&'a D<'a>` cannot be satisfied when `D<'a>` implements
24+
// `Drop`.)
25+
26+
#![feature(unsafe_destructor)]
27+
28+
use std::cell::Cell;
29+
30+
struct D<'a> {
31+
name: String,
32+
p: Cell<Option<&'a D<'a>>>,
33+
}
34+
35+
impl<'a> D<'a> {
36+
fn new(name: String) -> D<'a> { D { name: name, p: Cell::new(None) } }
37+
}
38+
39+
#[unsafe_destructor]
40+
impl<'a> Drop for D<'a> {
41+
fn drop(&mut self) {
42+
println!("dropping {} whose sibling is {:?}",
43+
self.name, self.p.get().map(|d| &d.name));
44+
}
45+
}
46+
47+
fn g() {
48+
let (d1, d2) = (D::new(format!("d1")), D::new(format!("d2")));
49+
d1.p.set(Some(&d2)); //~ ERROR `d2` does not live long enough
50+
d2.p.set(Some(&d1)); //~ ERROR `d1` does not live long enough
51+
}
52+
53+
fn main() {
54+
g();
55+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Reject mixing cyclic structure and Drop when using TypedArena.
12+
//
13+
// (Compare against compile-fail/dropck_vec_cycle_checked.rs)
14+
//
15+
// (Also compare against compile-fail/dropck_tarena_unsound_drop.rs,
16+
// which is a reduction of this code to more directly show the reason
17+
// for the error message we see here.)
18+
19+
#![allow(unstable)]
20+
#![feature(unsafe_destructor)]
21+
22+
extern crate arena;
23+
24+
use arena::TypedArena;
25+
use std::cell::Cell;
26+
use id::Id;
27+
28+
mod s {
29+
#![allow(unstable)]
30+
use std::sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering};
31+
32+
static S_COUNT: AtomicUint = ATOMIC_UINT_INIT;
33+
34+
pub fn next_count() -> usize {
35+
S_COUNT.fetch_add(1, Ordering::SeqCst) + 1
36+
}
37+
}
38+
39+
mod id {
40+
use s;
41+
#[derive(Debug)]
42+
pub struct Id {
43+
orig_count: usize,
44+
count: usize,
45+
}
46+
47+
impl Id {
48+
pub fn new() -> Id {
49+
let c = s::next_count();
50+
println!("building Id {}", c);
51+
Id { orig_count: c, count: c }
52+
}
53+
pub fn count(&self) -> usize {
54+
println!("Id::count on {} returns {}", self.orig_count, self.count);
55+
self.count
56+
}
57+
}
58+
59+
impl Drop for Id {
60+
fn drop(&mut self) {
61+
println!("dropping Id {}", self.count);
62+
self.count = 0;
63+
}
64+
}
65+
}
66+
67+
trait HasId {
68+
fn count(&self) -> usize;
69+
}
70+
71+
#[derive(Debug)]
72+
struct CheckId<T:HasId> {
73+
v: T
74+
}
75+
76+
#[allow(non_snake_case)]
77+
fn CheckId<T:HasId>(t: T) -> CheckId<T> { CheckId{ v: t } }
78+
79+
#[unsafe_destructor]
80+
impl<T:HasId> Drop for CheckId<T> {
81+
fn drop(&mut self) {
82+
assert!(self.v.count() > 0);
83+
}
84+
}
85+
86+
#[derive(Debug)]
87+
struct C<'a> {
88+
id: Id,
89+
v: Vec<CheckId<Cell<Option<&'a C<'a>>>>>,
90+
}
91+
92+
impl<'a> HasId for Cell<Option<&'a C<'a>>> {
93+
fn count(&self) -> usize {
94+
match self.get() {
95+
None => 1,
96+
Some(c) => c.id.count(),
97+
}
98+
}
99+
}
100+
101+
impl<'a> C<'a> {
102+
fn new() -> C<'a> {
103+
C { id: Id::new(), v: Vec::new() }
104+
}
105+
}
106+
107+
fn f<'a>(arena: &'a TypedArena<C<'a>>) {
108+
let c1 = arena.alloc(C::new());
109+
let c2 = arena.alloc(C::new());
110+
let c3 = arena.alloc(C::new());
111+
112+
c1.v.push(CheckId(Cell::new(None)));
113+
c1.v.push(CheckId(Cell::new(None)));
114+
c2.v.push(CheckId(Cell::new(None)));
115+
c2.v.push(CheckId(Cell::new(None)));
116+
c3.v.push(CheckId(Cell::new(None)));
117+
c3.v.push(CheckId(Cell::new(None)));
118+
119+
c1.v[0].v.set(Some(c2));
120+
c1.v[1].v.set(Some(c3));
121+
c2.v[0].v.set(Some(c2));
122+
c2.v[1].v.set(Some(c3));
123+
c3.v[0].v.set(Some(c1));
124+
c3.v[1].v.set(Some(c2));
125+
}
126+
127+
fn main() {
128+
let arena = TypedArena::new();
129+
f(&arena); //~ ERROR `arena` does not live long enough
130+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Check that a arena (TypedArena) cannot carry elements whose drop
12+
// methods might access borrowed data of lifetime that does not
13+
// strictly outlive the arena itself.
14+
//
15+
// Compare against run-pass/dropck_tarena_sound_drop.rs, which shows a
16+
// similar setup, but loosens `f` so that the struct `C<'a>` can be
17+
// fed a lifetime longer than that of the arena.
18+
//
19+
// (Also compare against dropck_tarena_cycle_checked.rs, from which
20+
// this was reduced to better understand its error message.)
21+
22+
#![allow(unstable)]
23+
#![feature(unsafe_destructor)]
24+
25+
extern crate arena;
26+
27+
use arena::TypedArena;
28+
29+
trait HasId { fn count(&self) -> usize; }
30+
31+
struct CheckId<T:HasId> { v: T }
32+
33+
// In the code below, the impl of HasId for `&'a usize` does not
34+
// actually access the borrowed data, but the point is that the
35+
// interface to CheckId does not (and cannot) know that, and therefore
36+
// when encountering the a value V of type CheckId<S>, we must
37+
// conservatively force the type S to strictly outlive V.
38+
#[unsafe_destructor]
39+
impl<T:HasId> Drop for CheckId<T> {
40+
fn drop(&mut self) {
41+
assert!(self.v.count() > 0);
42+
}
43+
}
44+
45+
struct C<'a> { v: CheckId<&'a usize>, }
46+
47+
impl<'a> HasId for &'a usize { fn count(&self) -> usize { 1 } }
48+
49+
fn f<'a>(_arena: &'a TypedArena<C<'a>>) {}
50+
51+
fn main() {
52+
let arena: TypedArena<C> = TypedArena::new();
53+
f(&arena); //~ ERROR `arena` does not live long enough
54+
}

0 commit comments

Comments
 (0)