@@ -92,13 +92,17 @@ impl<T> Retained<T> {
9292 ///
9393 /// The caller must ensure the given object reference has +1 retain count.
9494 ///
95- /// Additionally, there must be no [`Owned`] pointers to the same object.
95+ /// Additionally, there must be no [`Owned`] pointers or mutable
96+ /// references to the same object.
9697 ///
97- /// TODO: Something about there not being any mutable references.
98+ /// And lastly, the object pointer must be valid as a reference (non-null,
99+ /// aligned, dereferencable, initialized and upholds aliasing rules, see
100+ /// the [`std::ptr`] module for more information).
98101 #[ inline]
99- pub unsafe fn new ( obj : & T ) -> Self {
102+ pub unsafe fn new ( ptr : * const T ) -> Self {
100103 Self {
101- ptr : obj. into ( ) ,
104+ // SAFETY: Upheld by the caller
105+ ptr : NonNull :: new_unchecked ( ptr as * mut T ) ,
102106 phantom : PhantomData ,
103107 }
104108 }
@@ -117,6 +121,10 @@ impl<T> Retained<T> {
117121 ///
118122 /// The caller must ensure that there are no [`Owned`] pointers to the
119123 /// same object.
124+ ///
125+ /// Additionally, the object pointer must be valid as a reference
126+ /// (non-null, aligned, dereferencable, initialized and upholds aliasing
127+ /// rules, see the [`std::ptr`] module for more information).
120128 //
121129 // So this would be illegal:
122130 // ```rust
@@ -131,12 +139,14 @@ impl<T> Retained<T> {
131139 #[ doc( alias = "objc_retain" ) ]
132140 // Inlined since it's `objc_retain` that does the work.
133141 #[ cfg_attr( debug_assertions, inline) ]
134- pub unsafe fn retain ( obj : & T ) -> Self {
142+ pub unsafe fn retain ( ptr : * const T ) -> Self {
135143 // SAFETY: The caller upholds that the pointer is valid
136- let rtn = runtime:: objc_retain ( obj as * const T as * mut Object ) ;
137- debug_assert_eq ! ( rtn, obj as * const T as * mut Object ) ;
144+ let rtn = runtime:: objc_retain ( ptr as * mut Object ) as * const T ;
145+ debug_assert_eq ! ( rtn, ptr ) ;
138146 Self {
139- ptr : obj. into ( ) ,
147+ // SAFETY: Non-null upheld by the caller and `objc_retain` always
148+ // returns the same pointer.
149+ ptr : NonNull :: new_unchecked ( rtn as * mut T ) ,
140150 phantom : PhantomData ,
141151 }
142152 }
@@ -234,7 +244,7 @@ impl<T> Clone for Retained<T> {
234244 #[ inline]
235245 fn clone ( & self ) -> Self {
236246 // SAFETY: The `ptr` is guaranteed to be valid
237- unsafe { Self :: retain ( & * self ) }
247+ unsafe { Self :: retain ( self . as_ptr ( ) ) }
238248 }
239249}
240250
@@ -312,7 +322,6 @@ impl<T> From<Owned<T>> for Retained<T> {
312322#[ cfg( test) ]
313323mod tests {
314324 use core:: mem:: size_of;
315- use core:: ptr:: NonNull ;
316325
317326 use super :: Retained ;
318327 use crate :: runtime:: Object ;
0 commit comments