File tree Expand file tree Collapse file tree 2 files changed +41
-0
lines changed Expand file tree Collapse file tree 2 files changed +41
-0
lines changed Original file line number Diff line number Diff 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" ]
Original file line number Diff line number Diff 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 ( 0 u) ;
134+ c1. set ( 1 u) ;
135+ assert_eq ! ( 1 u, unsafe { * c1. as_unsafe_cell( ) . get( ) } ) ;
136+
137+ let c2: Cell < uint > = Cell :: new ( 0 u) ;
138+ unsafe { * c2. as_unsafe_cell ( ) . get ( ) = 1 u; }
139+ assert_eq ! ( 1 u, c2. get( ) ) ;
140+
141+ let r1: RefCell < uint > = RefCell :: new ( 0 u) ;
142+ * r1. borrow_mut ( ) = 1 u;
143+ assert_eq ! ( 1 u, unsafe { * r1. as_unsafe_cell( ) . get( ) } ) ;
144+
145+ let r2: RefCell < uint > = RefCell :: new ( 0 u) ;
146+ unsafe { * r2. as_unsafe_cell ( ) . get ( ) = 1 u; }
147+ assert_eq ! ( 1 u, * r2. borrow( ) ) ;
148+ }
You can’t perform that action at this time.
0 commit comments