Skip to content

Commit 1b9a16c

Browse files
committed
librustc: Require lifetimes within the types of values with destructors
to have strictly greater lifetime than the values themselves. Additionally, remove `#[unsafe_destructor]` in favor of these new restrictions. This broke a fair amount of code that had to do with `RefCell`s. We will probably need to do some work to improve the resulting ergonomics. Most code that broke looked like: match foo.bar.borrow().baz { ... } use_foo(&mut foo); Change this code to: { let bar = foo.bar.borrow(); match bar.baz { ... } } use_foo(&mut foo); This fixes an important memory safety hole relating to destructors, represented by issue rust-lang#8861. [breaking-change]
1 parent 828e075 commit 1b9a16c

File tree

42 files changed

+1160
-645
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1160
-645
lines changed

src/libcollections/treemap.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,27 +1084,29 @@ impl<T: Ord> Set<T> for TreeSet<T> {
10841084
}
10851085

10861086
fn is_subset(&self, other: &TreeSet<T>) -> bool {
1087-
let mut x = self.iter();
1088-
let mut y = other.iter();
1089-
let mut a = x.next();
1090-
let mut b = y.next();
1091-
while a.is_some() {
1092-
if b.is_none() {
1093-
return false;
1094-
}
1087+
{
1088+
let mut x = self.iter();
1089+
let mut y = other.iter();
1090+
let mut a = x.next();
1091+
let mut b = y.next();
1092+
while a.is_some() {
1093+
if b.is_none() {
1094+
return false;
1095+
}
10951096

1096-
let a1 = a.unwrap();
1097-
let b1 = b.unwrap();
1097+
let a1 = a.unwrap();
1098+
let b1 = b.unwrap();
10981099

1099-
match b1.cmp(a1) {
1100-
Less => (),
1101-
Greater => return false,
1102-
Equal => a = x.next(),
1103-
}
1100+
match b1.cmp(a1) {
1101+
Less => (),
1102+
Greater => return false,
1103+
Equal => a = x.next(),
1104+
}
11041105

1105-
b = y.next();
1106+
b = y.next();
1107+
}
1108+
true
11061109
}
1107-
true
11081110
}
11091111
}
11101112

src/libcore/cell.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,11 @@ impl<T> RefCell<T> {
310310

311311
#[unstable = "waiting for `Clone` to become stable"]
312312
impl<T: Clone> Clone for RefCell<T> {
313-
fn clone(&self) -> RefCell<T> {
314-
RefCell::new(self.borrow().clone())
313+
fn clone<'a>(&'a self) -> RefCell<T> {
314+
{
315+
let borrowed: Ref<'a,T> = self.borrow();
316+
RefCell::new(borrowed.clone())
317+
}
315318
}
316319
}
317320

src/libcore/finally.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,16 +90,22 @@ impl<T> Finally<T> for fn() -> T {
9090
* })
9191
* ```
9292
*/
93-
pub fn try_finally<T,U,R>(mutate: &mut T,
94-
drop: U,
95-
try_fn: |&mut T, U| -> R,
96-
finally_fn: |&mut T|)
97-
-> R {
98-
let f = Finallyalizer {
99-
mutate: mutate,
100-
dtor: finally_fn,
101-
};
102-
try_fn(&mut *f.mutate, drop)
93+
pub fn try_finally<'a,
94+
T,
95+
U,
96+
R>(
97+
mutate: &'a mut T,
98+
drop: U,
99+
try_fn: |&mut T, U| -> R,
100+
finally_fn: |&mut T|:'a)
101+
-> R {
102+
{
103+
let f: Finallyalizer<'a,T> = Finallyalizer {
104+
mutate: mutate,
105+
dtor: finally_fn,
106+
};
107+
try_fn(&mut *f.mutate, drop)
108+
}
103109
}
104110

105111
struct Finallyalizer<'a,A:'a> {

src/libgreen/basic.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,13 @@ impl BasicLoop {
6161

6262
fn remote_work(&mut self) {
6363
let messages = unsafe {
64-
mem::replace(&mut *self.messages.lock(), Vec::new())
64+
let lock = &mut *self.messages.lock();
65+
mem::replace(lock, Vec::new())
6566
};
66-
for message in messages.move_iter() {
67-
self.message(message);
67+
{
68+
for message in messages.move_iter() {
69+
self.message(message);
70+
}
6871
}
6972
}
7073

src/librustc/driver/session.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,10 @@ pub fn build_session_(sopts: config::Options,
258258
recursion_limit: Cell::new(64),
259259
};
260260

261-
sess.lint_store.borrow_mut().register_builtin(Some(&sess));
261+
{
262+
sess.lint_store.borrow_mut().register_builtin(Some(&sess));
263+
}
264+
262265
sess
263266
}
264267

src/librustc/front/feature_gate.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,8 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
244244
"unsafe_destructor") {
245245
self.gate_feature("unsafe_destructor",
246246
i.span,
247-
"`#[unsafe_destructor]` allows too \
248-
many unsafe patterns and may be \
249-
removed in the future");
247+
"`#[unsafe_destructor]` does nothing \
248+
anymore")
250249
}
251250
}
252251

src/librustc/metadata/tydecode.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,9 @@ fn parse_region(st: &mut PState, conv: conv_did) -> ty::Region {
318318
't' => {
319319
ty::ReStatic
320320
}
321+
'n' => {
322+
ty::ReFunction
323+
}
321324
'e' => {
322325
ty::ReStatic
323326
}

src/librustc/metadata/tyencode.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ pub fn enc_region(w: &mut SeekableMemWriter, cx: &ctxt, r: ty::Region) {
149149
ty::ReScope(nid) => {
150150
mywrite!(w, "s{}|", nid);
151151
}
152+
ty::ReFunction => {
153+
mywrite!(w, "n");
154+
}
152155
ty::ReStatic => {
153156
mywrite!(w, "t");
154157
}

src/librustc/middle/astencode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ impl tr for ty::Region {
490490
ty::ReScope(id) => {
491491
ty::ReScope(dcx.tr_id(id))
492492
}
493-
ty::ReEmpty | ty::ReStatic | ty::ReInfer(..) => {
493+
ty::ReEmpty | ty::ReStatic | ty::ReInfer(..) | ty::ReFunction => {
494494
*self
495495
}
496496
ty::ReFree(ref fr) => {

0 commit comments

Comments
 (0)