@@ -57,11 +57,11 @@ impl<T> Memory<T> {
5757 self . entries . borrow ( ) . len ( )
5858 }
5959
60- // Returns a key and a pointer to the inserted entry.
60+ // Returns a pointer to the inserted entry.
6161 //
6262 // SAFETY: The returned pointer is guaranteed to be valid until the entry
6363 // is removed or the Memory is dropped.
64- fn insert ( & self , e : T ) -> Result < ( usize , * const T ) , InsertError < T > > {
64+ fn insert ( & self , e : T ) -> Result < * const T , InsertError < T > > {
6565 let mut entries = self . entries . borrow_mut ( ) ;
6666
6767 // Out of capacity. By preventing inserts beyond the capacity, we
@@ -79,13 +79,19 @@ impl<T> Memory<T> {
7979 // therefore we can return a pointer to the element and guarantee
8080 // its validity until the element is removed.
8181
82- Ok ( ( key , entry as * const T ) )
82+ Ok ( entry as * const T )
8383 }
8484
85+ // SAFETY: `ptr` must be a valid pointer returned by `insert` that has
86+ // not yet been removed.
8587 #[ allow( clippy:: let_unit_value) ]
86- fn remove ( & self , key : usize ) {
88+ unsafe fn remove ( & self , ptr : * const T ) {
89+ let mut entries = self . entries . borrow_mut ( ) ;
90+
91+ let key = entries. key_of ( & * ptr) ;
92+
8793 // Ensure remove() method doesn't return a value
88- let _: ( ) = self . entries . borrow_mut ( ) . remove ( key) ;
94+ let _: ( ) = entries. remove ( key) ;
8995 }
9096
9197 // Returns a pointer to an entry if it exists.
@@ -111,10 +117,10 @@ fn unlikely_abort() {
111117 abort ( ) ;
112118}
113119
120+ #[ repr( C , align( 2 ) ) ]
114121pub struct RcInner < T > {
115122 refs : Cell < usize > ,
116123 memory : Cell < Option < std:: rc:: Rc < RcMemory < T > > > > ,
117- key : Cell < usize > ,
118124 value : T ,
119125}
120126
@@ -163,7 +169,6 @@ impl<T> Rc<T> {
163169 let ptr = Box :: leak ( Box :: new ( RcInner {
164170 refs : Cell :: new ( 1 ) ,
165171 memory : Cell :: new ( None ) ,
166- key : Cell :: new ( 0 ) ,
167172 value : v,
168173 } ) ) ;
169174
@@ -174,11 +179,10 @@ impl<T> Rc<T> {
174179 }
175180
176181 pub fn try_new_in ( v : T , memory : & std:: rc:: Rc < RcMemory < T > > ) -> Result < Self , AllocError > {
177- let ( key , ptr) = memory
182+ let ptr = memory
178183 . insert ( RcInner {
179184 refs : Cell :: new ( 1 ) ,
180185 memory : Cell :: new ( Some ( std:: rc:: Rc :: clone ( memory) ) ) ,
181- key : Cell :: new ( 0 ) ,
182186 value : v,
183187 } )
184188 . map_err ( |_| AllocError ) ?;
@@ -187,9 +191,6 @@ impl<T> Rc<T> {
187191 // despite casting it to *mut in order to construct NonNull
188192 let ptr = unsafe { NonNull :: new_unchecked ( ptr as * mut RcInner < T > ) } ;
189193
190- // SAFETY: ptr is convertible to a reference
191- unsafe { ptr. as_ref ( ) . key . set ( key) } ;
192-
193194 Ok ( Self {
194195 ptr,
195196 phantom : PhantomData ,
@@ -215,9 +216,8 @@ impl<T> Rc<T> {
215216 // Rc is moved out of the entry above, and it is dropped only
216217 // after the entry is removed.
217218
218- let key = self . inner ( ) . key . get ( ) ;
219-
220- memory. remove ( key) ;
219+ // SAFETY: While this Rc is alive, ptr is always valid
220+ unsafe { memory. remove ( self . ptr . as_ref ( ) ) } ;
221221 } else {
222222 // If there is no reference to slab memory, then the memory is
223223 // managed by the system allocator. To free it, we simply convert
0 commit comments