Skip to content

Commit 214d527

Browse files
committed
WIP: rc::MaybeOwnership + rc::Unknown
1 parent 79661f9 commit 214d527

File tree

5 files changed

+80
-21
lines changed

5 files changed

+80
-21
lines changed

objc2/src/__macro_helpers.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::rc::{Allocated, Id, Ownership};
1+
use crate::rc::{Allocated, Id, MaybeOwnership};
22
use crate::runtime::{Class, Sel};
33
use crate::{Message, MessageArguments, MessageReceiver};
44

@@ -51,7 +51,7 @@ pub trait MsgSendId<T, U> {
5151
}
5252

5353
// `new`
54-
impl<T: ?Sized + Message, O: Ownership> MsgSendId<&'_ Class, Id<T, O>>
54+
impl<T: ?Sized + Message, O: MaybeOwnership> MsgSendId<&'_ Class, Id<T, O>>
5555
for RetainSemantics<true, false, false, false>
5656
{
5757
#[inline]
@@ -69,7 +69,7 @@ impl<T: ?Sized + Message, O: Ownership> MsgSendId<&'_ Class, Id<T, O>>
6969
}
7070

7171
// `alloc`
72-
impl<T: ?Sized + Message, O: Ownership> MsgSendId<&'_ Class, Id<Allocated<T>, O>>
72+
impl<T: ?Sized + Message, O: MaybeOwnership> MsgSendId<&'_ Class, Id<Allocated<T>, O>>
7373
for RetainSemantics<false, true, false, false>
7474
{
7575
#[inline]
@@ -87,7 +87,7 @@ impl<T: ?Sized + Message, O: Ownership> MsgSendId<&'_ Class, Id<Allocated<T>, O>
8787
}
8888

8989
// `init`
90-
impl<T: ?Sized + Message, O: Ownership> MsgSendId<Option<Id<Allocated<T>, O>>, Id<T, O>>
90+
impl<T: ?Sized + Message, O: MaybeOwnership> MsgSendId<Option<Id<Allocated<T>, O>>, Id<T, O>>
9191
for RetainSemantics<false, false, true, false>
9292
{
9393
#[inline]
@@ -111,7 +111,7 @@ impl<T: ?Sized + Message, O: Ownership> MsgSendId<Option<Id<Allocated<T>, O>>, I
111111
}
112112

113113
// `copy` and `mutableCopy`
114-
impl<T: MessageReceiver, U: ?Sized + Message, O: Ownership> MsgSendId<T, Id<U, O>>
114+
impl<T: MessageReceiver, U: ?Sized + Message, O: MaybeOwnership> MsgSendId<T, Id<U, O>>
115115
for RetainSemantics<false, false, false, true>
116116
{
117117
#[inline]
@@ -126,7 +126,7 @@ impl<T: MessageReceiver, U: ?Sized + Message, O: Ownership> MsgSendId<T, Id<U, O
126126
}
127127

128128
// All other selectors
129-
impl<T: MessageReceiver, U: Message, O: Ownership> MsgSendId<T, Id<U, O>>
129+
impl<T: MessageReceiver, U: Message, O: MaybeOwnership> MsgSendId<T, Id<U, O>>
130130
for RetainSemantics<false, false, false, false>
131131
{
132132
#[inline]

objc2/src/message/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use core::mem;
22
use core::mem::ManuallyDrop;
33
use core::ptr::NonNull;
44

5-
use crate::rc::{Id, Owned, Ownership};
5+
use crate::rc::{Id, MaybeOwnership, Owned};
66
use crate::runtime::{Class, Imp, Object, Sel};
77
use crate::{Encode, EncodeArguments, RefEncode};
88

@@ -115,10 +115,10 @@ pub(crate) mod private {
115115
impl<'a, T: Message + ?Sized> Sealed for &'a T {}
116116
impl<'a, T: Message + ?Sized> Sealed for &'a mut T {}
117117

118-
impl<'a, T: Message + ?Sized, O: Ownership> Sealed for &'a Id<T, O> {}
118+
impl<'a, T: Message + ?Sized, O: MaybeOwnership> Sealed for &'a Id<T, O> {}
119119
impl<'a, T: Message + ?Sized> Sealed for &'a mut Id<T, Owned> {}
120120

121-
impl<T: Message + ?Sized, O: Ownership> Sealed for ManuallyDrop<Id<T, O>> {}
121+
impl<T: Message + ?Sized, O: MaybeOwnership> Sealed for ManuallyDrop<Id<T, O>> {}
122122

123123
impl Sealed for *const Class {}
124124
impl<'a> Sealed for &'a Class {}
@@ -266,7 +266,7 @@ unsafe impl<'a, T: Message + ?Sized> MessageReceiver for &'a mut T {
266266
}
267267
}
268268

269-
unsafe impl<'a, T: Message + ?Sized, O: Ownership> MessageReceiver for &'a Id<T, O> {
269+
unsafe impl<'a, T: Message + ?Sized, O: MaybeOwnership> MessageReceiver for &'a Id<T, O> {
270270
#[inline]
271271
fn __as_raw_receiver(self) -> *mut Object {
272272
(Id::as_ptr(self) as *mut T).cast()
@@ -280,7 +280,7 @@ unsafe impl<'a, T: Message + ?Sized> MessageReceiver for &'a mut Id<T, Owned> {
280280
}
281281
}
282282

283-
unsafe impl<T: Message + ?Sized, O: Ownership> MessageReceiver for ManuallyDrop<Id<T, O>> {
283+
unsafe impl<T: Message + ?Sized, O: MaybeOwnership> MessageReceiver for ManuallyDrop<Id<T, O>> {
284284
#[inline]
285285
fn __as_raw_receiver(self) -> *mut Object {
286286
Id::consume_as_ptr(self).cast()

objc2/src/rc/id.rs

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use core::ptr::NonNull;
77

88
use super::Allocated;
99
use super::AutoreleasePool;
10-
use super::{Owned, Ownership, Shared};
10+
use super::{MaybeOwnership, Owned, Ownership, Shared, Unknown};
1111
use crate::ffi;
1212
use crate::Message;
1313

@@ -101,7 +101,7 @@ use crate::Message;
101101
// TODO: Figure out if `Message` bound on `T` would be better here?
102102
// TODO: Add `ptr::Thin` bound on `T` to allow for only extern types
103103
// TODO: Consider changing the name of Id -> Retain
104-
pub struct Id<T: ?Sized, O: Ownership> {
104+
pub struct Id<T: ?Sized, O: MaybeOwnership> {
105105
/// A pointer to the contained object. The pointer is always retained.
106106
///
107107
/// It is important that this is `NonNull`, since we want to dereference
@@ -125,7 +125,7 @@ pub struct Id<T: ?Sized, O: Ownership> {
125125
notunwindsafe: PhantomData<&'static mut ()>,
126126
}
127127

128-
impl<T: ?Sized, O: Ownership> Id<T, O> {
128+
impl<T: ?Sized, O: MaybeOwnership> Id<T, O> {
129129
#[inline]
130130
unsafe fn new_nonnull(ptr: NonNull<T>) -> Self {
131131
Self {
@@ -137,7 +137,7 @@ impl<T: ?Sized, O: Ownership> Id<T, O> {
137137
}
138138
}
139139

140-
impl<T: Message + ?Sized, O: Ownership> Id<Allocated<T>, O> {
140+
impl<T: Message + ?Sized, O: MaybeOwnership> Id<Allocated<T>, O> {
141141
#[inline]
142142
pub(crate) unsafe fn new_allocated(ptr: *mut T) -> Option<Self> {
143143
// SAFETY: Upheld by the caller
@@ -158,7 +158,7 @@ impl<T: Message + ?Sized, O: Ownership> Id<Allocated<T>, O> {
158158
}
159159
}
160160

161-
impl<T: Message + ?Sized, O: Ownership> Id<T, O> {
161+
impl<T: Message + ?Sized, O: MaybeOwnership> Id<T, O> {
162162
/// Constructs an [`Id`] to an object that already has +1 retain count.
163163
///
164164
/// This is useful when you have a retain count that has been handed off
@@ -258,7 +258,7 @@ impl<T: Message + ?Sized> Id<T, Owned> {
258258
}
259259

260260
// TODO: Add ?Sized bound
261-
impl<T: Message, O: Ownership> Id<T, O> {
261+
impl<T: Message, O: MaybeOwnership> Id<T, O> {
262262
/// Convert the type of the given object to another.
263263
///
264264
/// This is equivalent to a `cast` between two pointers.
@@ -546,6 +546,38 @@ impl<T: Message> Id<T, Shared> {
546546
}
547547
}
548548

549+
impl<T: Message + ?Sized> Id<T, Unknown> {
550+
/// TODO
551+
#[inline]
552+
pub unsafe fn into_owned(self) -> Id<T, Owned> {
553+
unsafe { self.into_ownership() }
554+
}
555+
556+
/// TODO
557+
#[inline]
558+
pub unsafe fn into_shared(self) -> Id<T, Shared> {
559+
unsafe { self.into_ownership() }
560+
}
561+
562+
/// TODO
563+
#[inline]
564+
pub unsafe fn into_ownership<O: Ownership>(self) -> Id<T, O> {
565+
let ptr = ManuallyDrop::new(self).ptr;
566+
unsafe { Id::new_nonnull(ptr) }
567+
}
568+
}
569+
570+
impl<T: Message> Id<T, Unknown> {
571+
/// TODO
572+
#[doc(alias = "objc_autorelease")]
573+
#[must_use = "If you don't intend to use the object any more, just drop it as usual"]
574+
#[inline]
575+
pub fn autorelease(self, pool: &AutoreleasePool) -> *mut T {
576+
pool.__verify_is_inner();
577+
self.autorelease_inner()
578+
}
579+
}
580+
549581
impl<T: Message + ?Sized> From<Id<T, Owned>> for Id<T, Shared> {
550582
/// Downgrade from an owned to a shared [`Id`], allowing it to be cloned.
551583
#[inline]
@@ -556,6 +588,15 @@ impl<T: Message + ?Sized> From<Id<T, Owned>> for Id<T, Shared> {
556588
}
557589
}
558590

591+
impl<T: Message + ?Sized, O: Ownership> From<Id<T, O>> for Id<T, Unknown> {
592+
#[inline]
593+
fn from(obj: Id<T, O>) -> Self {
594+
let ptr = ManuallyDrop::new(obj).ptr;
595+
// SAFETY: The pointer is valid, and ownership is simply decreased
596+
unsafe { <Id<T, Unknown>>::new_nonnull(ptr) }
597+
}
598+
}
599+
559600
// TODO: Add ?Sized bound
560601
impl<T: Message> Clone for Id<T, Shared> {
561602
/// Makes a clone of the shared object.
@@ -580,7 +621,7 @@ impl<T: Message> Clone for Id<T, Shared> {
580621
/// borrowed data.
581622
///
582623
/// [dropck_eyepatch]: https://doc.rust-lang.org/nightly/nomicon/dropck.html#an-escape-hatch
583-
impl<T: ?Sized, O: Ownership> Drop for Id<T, O> {
624+
impl<T: ?Sized, O: MaybeOwnership> Drop for Id<T, O> {
584625
/// Releases the retained object.
585626
///
586627
/// The contained object's destructor (if it has one) is never run!
@@ -624,6 +665,9 @@ unsafe impl<T: Send + ?Sized> Send for Id<T, Owned> {}
624665
/// access as having a `T` directly.
625666
unsafe impl<T: Sync + ?Sized> Sync for Id<T, Owned> {}
626667

668+
// TODO: Maybe implement Send and Sync for `O: Unknown`?
669+
670+
// Explicitly using `Ownership` and not `MaybeOwnership` here!
627671
impl<T: ?Sized, O: Ownership> Deref for Id<T, O> {
628672
type Target = T;
629673

@@ -647,7 +691,7 @@ impl<T: ?Sized> DerefMut for Id<T, Owned> {
647691
}
648692
}
649693

650-
impl<T: ?Sized, O: Ownership> fmt::Pointer for Id<T, O> {
694+
impl<T: ?Sized, O: MaybeOwnership> fmt::Pointer for Id<T, O> {
651695
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
652696
fmt::Pointer::fmt(&self.ptr.as_ptr(), f)
653697
}
@@ -657,8 +701,11 @@ impl<T: ?Sized, O: Ownership> fmt::Pointer for Id<T, O> {
657701
//
658702
// See https://doc.rust-lang.org/1.54.0/src/alloc/boxed.rs.html#1652-1675
659703
// and the `Arc` implementation.
704+
//
705+
// TODO: MaybeOwnership?
660706
impl<T: ?Sized, O: Ownership> Unpin for Id<T, O> {}
661707

708+
// TODO: MaybeOwnership?
662709
impl<T: RefUnwindSafe + ?Sized, O: Ownership> RefUnwindSafe for Id<T, O> {}
663710

664711
// Same as `Arc<T>`.

objc2/src/rc/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub use self::allocated::Allocated;
7070
pub use self::autorelease::{autoreleasepool, AutoreleasePool, AutoreleaseSafe};
7171
pub use self::id::Id;
7272
pub use self::id_traits::{DefaultId, SliceId, SliceIdMut};
73-
pub use self::ownership::{Owned, Ownership, Shared};
73+
pub use self::ownership::{MaybeOwnership, Owned, Ownership, Shared, Unknown};
7474
pub use self::weak_id::WeakId;
7575

7676
#[cfg(test)]

objc2/src/rc/ownership.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,31 @@ pub enum Owned {}
88
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
99
pub enum Shared {}
1010

11+
/// TODO
12+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
13+
pub enum Unknown {}
14+
1115
mod private {
1216
pub trait Sealed {}
1317

1418
impl Sealed for super::Owned {}
1519
impl Sealed for super::Shared {}
20+
impl Sealed for super::Unknown {}
1621
}
1722

23+
/// TODO
24+
pub trait MaybeOwnership: private::Sealed + 'static {}
25+
26+
impl MaybeOwnership for Owned {}
27+
impl MaybeOwnership for Shared {}
28+
impl MaybeOwnership for Unknown {}
29+
1830
/// A type that marks what type of ownership a struct has over the object(s)
1931
/// it contains; specifically, either [`Owned`] or [`Shared`].
2032
///
2133
/// This trait is sealed and not meant to be implemented outside of the this
2234
/// crate.
23-
pub trait Ownership: private::Sealed + 'static {}
35+
pub trait Ownership: private::Sealed + MaybeOwnership + 'static {}
2436

2537
impl Ownership for Owned {}
2638
impl Ownership for Shared {}

0 commit comments

Comments
 (0)