@@ -9,10 +9,11 @@ use core::ptr::{drop_in_place, NonNull};
9
9
use super :: Retained ;
10
10
use crate :: runtime:: { self , Object } ;
11
11
12
- /// A smart pointer that strongly references and owns an Objective-C object.
12
+ /// A smart pointer that strongly references and uniquely owns an Objective-C
13
+ /// object.
13
14
///
14
- /// The fact that we own the pointer means that it's safe to mutate it. As
15
- /// such, this implements [`DerefMut`].
15
+ /// The fact that we uniquely own the pointer means that it's safe to mutate
16
+ /// it. As such, this implements [`DerefMut`].
16
17
///
17
18
/// This is guaranteed to have the same size as the underlying pointer.
18
19
///
@@ -34,29 +35,31 @@ use crate::runtime::{self, Object};
34
35
#[ repr( transparent) ]
35
36
pub struct Owned < T > {
36
37
/// The pointer is always retained.
37
- pub ( super ) ptr : NonNull < T > , // Covariant
38
- phantom : PhantomData < T > , // Necessary for dropcheck
38
+ ptr : NonNull < T > , // We are the unique owner of T, so covariance is correct
39
+ phantom : PhantomData < T > , // Necessary for dropck
39
40
}
40
41
41
- // SAFETY: TODO
42
+ /// `Owned` pointers are `Send` if `T` is `Send` because they give the same
43
+ /// access as having a T directly.
42
44
unsafe impl < T : Send > Send for Owned < T > { }
43
45
44
- // SAFETY: TODO
46
+ /// `Owned` pointers are `Sync` if `T` is `Sync` because they give the same
47
+ /// access as having a `T` directly.
45
48
unsafe impl < T : Sync > Sync for Owned < T > { }
46
49
47
50
// TODO: Unsure how the API should look...
48
51
impl < T > Owned < T > {
49
- /// TODO
52
+ /// Create a new `Owned` pointer to the object.
53
+ ///
54
+ /// Uses a retain count that has been handed off from somewhere else,
55
+ /// usually Objective-C methods like `init`, `alloc`, `new`, or `copy`.
50
56
///
51
57
/// # Safety
52
58
///
53
- /// The caller must ensure the given object reference has exactly 1 retain
54
- /// count (that is, a retain count that has been handed off from somewhere
55
- /// else, usually Objective-C methods like `init`, `alloc`, `new`, or
56
- /// `copy`).
59
+ /// The caller must ensure that there are no other pointers or references
60
+ /// to the same object, and the given reference is not be used afterwards.
57
61
///
58
- /// Additionally, there must be no other pointers or references to the same
59
- /// object, and the given reference must not be used afterwards.
62
+ /// Additionally, the given object reference must have +1 retain count.
60
63
///
61
64
/// # Example
62
65
///
@@ -70,6 +73,7 @@ impl<T> Owned<T> {
70
73
/// TODO: Something about there not being other references.
71
74
// Note: The fact that we take a `&mut` here is more of a lint; the lifetime
72
75
// information is lost, so whatever produced the reference can still be
76
+ // mutated or aliased afterwards.
73
77
#[ inline]
74
78
pub unsafe fn new ( obj : & mut T ) -> Self {
75
79
Self {
@@ -78,27 +82,37 @@ impl<T> Owned<T> {
78
82
}
79
83
}
80
84
81
- /// Construct an `Owned` pointer
85
+ /// Acquires a `*mut` pointer to the object.
86
+ #[ inline]
87
+ pub fn as_ptr ( & self ) -> * mut T {
88
+ self . ptr . as_ptr ( )
89
+ }
90
+
91
+ /// Construct an `Owned` pointer from a `Retained` pointer.
82
92
///
83
93
/// # Safety
84
94
///
85
95
/// The caller must ensure that there are no other pointers to the same
86
96
/// object (which also means that the given [`Retained`] should have a
87
- /// retain count of exactly 1).
97
+ /// retain count of exactly 1 in almost all cases ).
88
98
#[ inline]
89
99
pub unsafe fn from_retained ( obj : Retained < T > ) -> Self {
90
- let ptr = mem:: ManuallyDrop :: new ( obj) . ptr ;
100
+ // SAFETY: The pointer is guaranteed by `Retained` to be NonNull
101
+ let ptr = NonNull :: new_unchecked ( mem:: ManuallyDrop :: new ( obj) . as_ptr ( ) as * mut T ) ;
91
102
Self {
92
103
ptr,
93
104
phantom : PhantomData ,
94
105
}
95
106
}
96
107
}
97
108
98
- // TODO: #[may_dangle]
99
- // https://doc.rust-lang.org/nightly/nomicon/dropck.html
109
+ /// `#[may_dangle]` (see [this][dropck_eyepatch]) would not be safe here,
110
+ /// since we cannot verify that a `dealloc` method doesn't access borrowed
111
+ /// data.
112
+ ///
113
+ /// [dropck_eyepatch]: https://doc.rust-lang.org/nightly/nomicon/dropck.html#an-escape-hatch
100
114
impl < T > Drop for Owned < T > {
101
- /// Releases the retained object
115
+ /// Releases the retained object.
102
116
///
103
117
/// This is guaranteed to be the last destructor that runs, in contrast to
104
118
/// [`Retained`], which means that we can run the [`Drop`] implementation
@@ -114,8 +128,6 @@ impl<T> Drop for Owned<T> {
114
128
}
115
129
}
116
130
117
- // Note: `Clone` is not implemented for this!
118
-
119
131
impl < T > Deref for Owned < T > {
120
132
type Target = T ;
121
133
0 commit comments