auto merge of #18212 : kmcallister/rust/unsafecell, r=thestinger

Fixes #18131.
This commit is contained in:
bors 2014-10-26 06:37:23 +00:00
commit cb943b7d2b
2 changed files with 41 additions and 0 deletions

View file

@ -191,6 +191,17 @@ impl<T:Copy> Cell<T> {
*self.value.get() = value;
}
}
/// Get a reference to the underlying `UnsafeCell`.
///
/// This can be used to circumvent `Cell`'s safety checks.
///
/// This function is `unsafe` because `UnsafeCell`'s field is public.
#[inline]
#[experimental]
pub unsafe fn as_unsafe_cell<'a>(&'a self) -> &'a UnsafeCell<T> {
&self.value
}
}
#[unstable = "waiting for `Clone` trait to become stable"]
@ -306,6 +317,17 @@ impl<T> RefCell<T> {
None => fail!("RefCell<T> already borrowed")
}
}
/// Get a reference to the underlying `UnsafeCell`.
///
/// This can be used to circumvent `RefCell`'s safety checks.
///
/// This function is `unsafe` because `UnsafeCell`'s field is public.
#[inline]
#[experimental]
pub unsafe fn as_unsafe_cell<'a>(&'a self) -> &'a UnsafeCell<T> {
&self.value
}
}
#[unstable = "waiting for `Clone` to become stable"]

View file

@ -127,3 +127,22 @@ fn clone_ref_updates_flag() {
}
assert!(x.try_borrow_mut().is_some());
}
#[test]
fn as_unsafe_cell() {
let c1: Cell<uint> = Cell::new(0u);
c1.set(1u);
assert_eq!(1u, unsafe { *c1.as_unsafe_cell().get() });
let c2: Cell<uint> = Cell::new(0u);
unsafe { *c2.as_unsafe_cell().get() = 1u; }
assert_eq!(1u, c2.get());
let r1: RefCell<uint> = RefCell::new(0u);
*r1.borrow_mut() = 1u;
assert_eq!(1u, unsafe { *r1.as_unsafe_cell().get() });
let r2: RefCell<uint> = RefCell::new(0u);
unsafe { *r2.as_unsafe_cell().get() = 1u; }
assert_eq!(1u, *r2.borrow());
}