@@ -92,13 +92,17 @@ impl<T> Retained<T> {
92
92
///
93
93
/// The caller must ensure the given object reference has +1 retain count.
94
94
///
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.
96
97
///
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).
98
101
#[ inline]
99
- pub unsafe fn new ( obj : & T ) -> Self {
102
+ pub unsafe fn new ( ptr : * const T ) -> Self {
100
103
Self {
101
- ptr : obj. into ( ) ,
104
+ // SAFETY: Upheld by the caller
105
+ ptr : NonNull :: new_unchecked ( ptr as * mut T ) ,
102
106
phantom : PhantomData ,
103
107
}
104
108
}
@@ -117,6 +121,10 @@ impl<T> Retained<T> {
117
121
///
118
122
/// The caller must ensure that there are no [`Owned`] pointers to the
119
123
/// 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).
120
128
//
121
129
// So this would be illegal:
122
130
// ```rust
@@ -131,12 +139,14 @@ impl<T> Retained<T> {
131
139
#[ doc( alias = "objc_retain" ) ]
132
140
// Inlined since it's `objc_retain` that does the work.
133
141
#[ cfg_attr( debug_assertions, inline) ]
134
- pub unsafe fn retain ( obj : & T ) -> Self {
142
+ pub unsafe fn retain ( ptr : * const T ) -> Self {
135
143
// 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 ) ;
138
146
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 ) ,
140
150
phantom : PhantomData ,
141
151
}
142
152
}
@@ -234,7 +244,7 @@ impl<T> Clone for Retained<T> {
234
244
#[ inline]
235
245
fn clone ( & self ) -> Self {
236
246
// SAFETY: The `ptr` is guaranteed to be valid
237
- unsafe { Self :: retain ( & * self ) }
247
+ unsafe { Self :: retain ( self . as_ptr ( ) ) }
238
248
}
239
249
}
240
250
@@ -312,7 +322,6 @@ impl<T> From<Owned<T>> for Retained<T> {
312
322
#[ cfg( test) ]
313
323
mod tests {
314
324
use core:: mem:: size_of;
315
- use core:: ptr:: NonNull ;
316
325
317
326
use super :: Retained ;
318
327
use crate :: runtime:: Object ;
0 commit comments