Skip to content

Commit 054746a

Browse files
committed
Stop using transmute_mut in RefCell
This is supposedly undefined behavior now that Unsafe exists, so we'll use Cell instead.
1 parent 8801d89 commit 054746a

File tree

1 file changed

+17
-21
lines changed

1 file changed

+17
-21
lines changed

src/libstd/cell.rs

+17-21
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
//! Types dealing with dynamic mutability
1212
13-
use cast;
1413
use clone::Clone;
1514
use cmp::Eq;
1615
use fmt;
@@ -70,7 +69,7 @@ impl<T: Copy + fmt::Show> fmt::Show for Cell<T> {
7069
/// A mutable memory location with dynamically checked borrow rules
7170
pub struct RefCell<T> {
7271
value: Unsafe<T>,
73-
borrow: BorrowFlag,
72+
borrow: Cell<BorrowFlag>,
7473
nocopy: marker::NoCopy,
7574
noshare: marker::NoShare,
7675
}
@@ -86,33 +85,29 @@ impl<T> RefCell<T> {
8685
pub fn new(value: T) -> RefCell<T> {
8786
RefCell {
8887
value: Unsafe::new(value),
88+
borrow: Cell::new(UNUSED),
8989
nocopy: marker::NoCopy,
9090
noshare: marker::NoShare,
91-
borrow: UNUSED,
9291
}
9392
}
9493

9594
/// Consumes the `RefCell`, returning the wrapped value.
9695
pub fn unwrap(self) -> T {
97-
assert!(self.borrow == UNUSED);
96+
assert!(self.borrow.get() == UNUSED);
9897
unsafe{self.value.unwrap()}
9998
}
10099

101-
unsafe fn as_mut<'a>(&'a self) -> &'a mut RefCell<T> {
102-
cast::transmute_mut(self)
103-
}
104-
105100
/// Attempts to immutably borrow the wrapped value.
106101
///
107102
/// The borrow lasts until the returned `Ref` exits scope. Multiple
108103
/// immutable borrows can be taken out at the same time.
109104
///
110105
/// Returns `None` if the value is currently mutably borrowed.
111106
pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
112-
match self.borrow {
107+
match self.borrow.get() {
113108
WRITING => None,
114-
_ => {
115-
unsafe { self.as_mut().borrow += 1; }
109+
borrow => {
110+
self.borrow.set(borrow + 1);
116111
Some(Ref { parent: self })
117112
}
118113
}
@@ -140,11 +135,10 @@ impl<T> RefCell<T> {
140135
///
141136
/// Returns `None` if the value is currently borrowed.
142137
pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
143-
match self.borrow {
144-
UNUSED => unsafe {
145-
let mut_self = self.as_mut();
146-
mut_self.borrow = WRITING;
147-
Some(RefMut { parent: mut_self })
138+
match self.borrow.get() {
139+
UNUSED => {
140+
self.borrow.set(WRITING);
141+
Some(RefMut { parent: self })
148142
},
149143
_ => None
150144
}
@@ -186,8 +180,9 @@ pub struct Ref<'b, T> {
186180
#[unsafe_destructor]
187181
impl<'b, T> Drop for Ref<'b, T> {
188182
fn drop(&mut self) {
189-
assert!(self.parent.borrow != WRITING && self.parent.borrow != UNUSED);
190-
unsafe { self.parent.as_mut().borrow -= 1; }
183+
let borrow = self.parent.borrow.get();
184+
assert!(borrow != WRITING && borrow != UNUSED);
185+
self.parent.borrow.set(borrow - 1);
191186
}
192187
}
193188

@@ -200,14 +195,15 @@ impl<'b, T> Deref<T> for Ref<'b, T> {
200195

201196
/// Wraps a mutable borrowed reference to a value in a `RefCell` box.
202197
pub struct RefMut<'b, T> {
203-
parent: &'b mut RefCell<T>
198+
parent: &'b RefCell<T>
204199
}
205200

206201
#[unsafe_destructor]
207202
impl<'b, T> Drop for RefMut<'b, T> {
208203
fn drop(&mut self) {
209-
assert!(self.parent.borrow == WRITING);
210-
self.parent.borrow = UNUSED;
204+
let borrow = self.parent.borrow.get();
205+
assert!(borrow == WRITING);
206+
self.parent.borrow.set(UNUSED);
211207
}
212208
}
213209

0 commit comments

Comments
 (0)