about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-10-26 06:37:23 +0000
committerbors <bors@rust-lang.org>2014-10-26 06:37:23 +0000
commitcb943b7d2b179bdb0a97afedbbb092f1a7e7638c (patch)
treedc759920bbb21de10483a54fddf1290c5e027283
parentf168c12c5629afd45c9b3ed250350bf830b99642 (diff)
parent7317ef5c362bde766440f62e6c2ac8a210e6c22d (diff)
downloadrust-cb943b7d2b179bdb0a97afedbbb092f1a7e7638c.tar.gz
rust-cb943b7d2b179bdb0a97afedbbb092f1a7e7638c.zip
auto merge of #18212 : kmcallister/rust/unsafecell, r=thestinger
Fixes #18131.
-rw-r--r--src/libcore/cell.rs22
-rw-r--r--src/libcoretest/cell.rs19
2 files changed, 41 insertions, 0 deletions
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index d644fd0063e..8a4b9f6e51b 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -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"]
diff --git a/src/libcoretest/cell.rs b/src/libcoretest/cell.rs
index b3ae110363c..59365045f43 100644
--- a/src/libcoretest/cell.rs
+++ b/src/libcoretest/cell.rs
@@ -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());
+}