@@ -55,11 +55,11 @@ impl<T> Memory<T> {
5555 self . entries . borrow ( ) . len ( )
5656 }
5757
58- // Returns a pointer to the inserted entry.
58+ // Returns a key and a pointer to the inserted entry.
5959 //
6060 // SAFETY: The returned pointer is guaranteed to be valid until the entry
6161 // is removed or the Memory is dropped.
62- fn insert ( & self , e : T ) -> Result < * const T , InsertError < T > > {
62+ fn insert ( & self , e : T ) -> Result < ( usize , * const T ) , InsertError < T > > {
6363 let mut entries = self . entries . borrow_mut ( ) ;
6464
6565 // Out of capacity. By preventing inserts beyond the capacity, we
@@ -77,19 +77,11 @@ impl<T> Memory<T> {
7777 // therefore we can return a pointer to the element and guarantee
7878 // its validity until the element is removed.
7979
80- Ok ( entry as * const T )
80+ Ok ( ( key , entry as * const T ) )
8181 }
8282
83- // The specified pointer must be one returned by the insert method
84- unsafe fn remove ( & self , e : * const T ) {
85- let mut entries = self . entries . borrow_mut ( ) ;
86-
87- // SAFETY: We trust `e` is valid
88- let e: & T = unsafe { & * e } ;
89-
90- let key = entries. key_of ( e) ;
91-
92- entries. remove ( key) ;
83+ fn remove ( & self , key : usize ) {
84+ self . entries . borrow_mut ( ) . remove ( key) ;
9385 }
9486
9587 // Returns a pointer to an entry if it exists.
@@ -311,6 +303,7 @@ fn unlikely_abort() {
311303pub struct RcInner < T > {
312304 refs : Cell < usize > ,
313305 memory : std:: rc:: Rc < RcMemory < T > > ,
306+ key : Cell < usize > ,
314307 value : T ,
315308}
316309
@@ -357,10 +350,11 @@ pub struct Rc<T> {
357350impl < T > Rc < T > {
358351 #[ allow( clippy:: result_unit_err) ]
359352 pub fn new ( v : T , memory : & std:: rc:: Rc < RcMemory < T > > ) -> Result < Self , InsertError < T > > {
360- let ptr = memory
353+ let ( key , ptr) = memory
361354 . insert ( RcInner {
362355 refs : Cell :: new ( 1 ) ,
363356 memory : std:: rc:: Rc :: clone ( memory) ,
357+ key : Cell :: new ( 0 ) ,
364358 value : v,
365359 } )
366360 . map_err ( |e| InsertError ( e. 0 . value ) ) ?;
@@ -369,6 +363,9 @@ impl<T> Rc<T> {
369363 // despite casting it to *mut in order to construct NonNull
370364 let ptr = unsafe { NonNull :: new_unchecked ( ptr as * mut RcInner < T > ) } ;
371365
366+ // SAFETY: ptr is convertible to a reference
367+ unsafe { ptr. as_ref ( ) . key . set ( key) } ;
368+
372369 Ok ( Self {
373370 ptr,
374371 phantom : PhantomData ,
@@ -409,9 +406,9 @@ impl<T> Rc<T> {
409406 // before removing the entry.
410407
411408 let memory = std:: rc:: Rc :: clone ( & self . inner ( ) . memory ) ;
409+ let key = self . inner ( ) . key . get ( ) ;
412410
413- // SAFETY: While this Rc is alive, `ptr` is always valid
414- unsafe { memory. remove ( self . ptr . as_ptr ( ) ) } ;
411+ memory. remove ( key) ;
415412 }
416413}
417414
0 commit comments