@@ -9,10 +9,11 @@ use core::ptr::{drop_in_place, NonNull};
99use super :: Retained ;
1010use crate :: runtime:: { self , Object } ;
1111
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.
1314///
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`].
1617///
1718/// This is guaranteed to have the same size as the underlying pointer.
1819///
@@ -34,29 +35,31 @@ use crate::runtime::{self, Object};
3435#[ repr( transparent) ]
3536pub struct Owned < T > {
3637 /// 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
3940}
4041
41- // SAFETY: TODO
42+ /// `Owned` pointers are `Send` if `T` is `Send` because they give the same
43+ /// access as having a T directly.
4244unsafe impl < T : Send > Send for Owned < T > { }
4345
44- // SAFETY: TODO
46+ /// `Owned` pointers are `Sync` if `T` is `Sync` because they give the same
47+ /// access as having a `T` directly.
4548unsafe impl < T : Sync > Sync for Owned < T > { }
4649
4750// TODO: Unsure how the API should look...
4851impl < 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`.
5056 ///
5157 /// # Safety
5258 ///
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.
5761 ///
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.
6063 ///
6164 /// # Example
6265 ///
@@ -70,6 +73,7 @@ impl<T> Owned<T> {
7073 /// TODO: Something about there not being other references.
7174 // Note: The fact that we take a `&mut` here is more of a lint; the lifetime
7275 // information is lost, so whatever produced the reference can still be
76+ // mutated or aliased afterwards.
7377 #[ inline]
7478 pub unsafe fn new ( obj : & mut T ) -> Self {
7579 Self {
@@ -78,27 +82,37 @@ impl<T> Owned<T> {
7882 }
7983 }
8084
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.
8292 ///
8393 /// # Safety
8494 ///
8595 /// The caller must ensure that there are no other pointers to the same
8696 /// 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 ).
8898 #[ inline]
8999 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 ) ;
91102 Self {
92103 ptr,
93104 phantom : PhantomData ,
94105 }
95106 }
96107}
97108
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
100114impl < T > Drop for Owned < T > {
101- /// Releases the retained object
115+ /// Releases the retained object.
102116 ///
103117 /// This is guaranteed to be the last destructor that runs, in contrast to
104118 /// [`Retained`], which means that we can run the [`Drop`] implementation
@@ -114,8 +128,6 @@ impl<T> Drop for Owned<T> {
114128 }
115129}
116130
117- // Note: `Clone` is not implemented for this!
118-
119131impl < T > Deref for Owned < T > {
120132 type Target = T ;
121133
0 commit comments