Skip to content

Commit 7317ef5

Browse files
committed
Add as_unsafe_cell() for Cell and RefCell
Fixes rust-lang#18131.
1 parent a10917a commit 7317ef5

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

src/libcore/cell.rs

+22
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,17 @@ impl<T:Copy> Cell<T> {
191191
*self.value.get() = value;
192192
}
193193
}
194+
195+
/// Get a reference to the underlying `UnsafeCell`.
196+
///
197+
/// This can be used to circumvent `Cell`'s safety checks.
198+
///
199+
/// This function is `unsafe` because `UnsafeCell`'s field is public.
200+
#[inline]
201+
#[experimental]
202+
pub unsafe fn as_unsafe_cell<'a>(&'a self) -> &'a UnsafeCell<T> {
203+
&self.value
204+
}
194205
}
195206

196207
#[unstable = "waiting for `Clone` trait to become stable"]
@@ -306,6 +317,17 @@ impl<T> RefCell<T> {
306317
None => fail!("RefCell<T> already borrowed")
307318
}
308319
}
320+
321+
/// Get a reference to the underlying `UnsafeCell`.
322+
///
323+
/// This can be used to circumvent `RefCell`'s safety checks.
324+
///
325+
/// This function is `unsafe` because `UnsafeCell`'s field is public.
326+
#[inline]
327+
#[experimental]
328+
pub unsafe fn as_unsafe_cell<'a>(&'a self) -> &'a UnsafeCell<T> {
329+
&self.value
330+
}
309331
}
310332

311333
#[unstable = "waiting for `Clone` to become stable"]

src/libcoretest/cell.rs

+19
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,22 @@ fn clone_ref_updates_flag() {
127127
}
128128
assert!(x.try_borrow_mut().is_some());
129129
}
130+
131+
#[test]
132+
fn as_unsafe_cell() {
133+
let c1: Cell<uint> = Cell::new(0u);
134+
c1.set(1u);
135+
assert_eq!(1u, unsafe { *c1.as_unsafe_cell().get() });
136+
137+
let c2: Cell<uint> = Cell::new(0u);
138+
unsafe { *c2.as_unsafe_cell().get() = 1u; }
139+
assert_eq!(1u, c2.get());
140+
141+
let r1: RefCell<uint> = RefCell::new(0u);
142+
*r1.borrow_mut() = 1u;
143+
assert_eq!(1u, unsafe { *r1.as_unsafe_cell().get() });
144+
145+
let r2: RefCell<uint> = RefCell::new(0u);
146+
unsafe { *r2.as_unsafe_cell().get() = 1u; }
147+
assert_eq!(1u, *r2.borrow());
148+
}

0 commit comments

Comments
 (0)