Skip to content

Commit c05fb9a

Browse files
authored
Merge pull request #218 from madsmtm/better-ownership-generics
Make traits that `Owned` and `Shared` implement supertraits of `Ownership`
2 parents c499a56 + d80ecbd commit c05fb9a

File tree

4 files changed

+80
-7
lines changed

4 files changed

+80
-7
lines changed

objc2-foundation/src/array.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ mod tests {
246246
use objc2::rc::autoreleasepool;
247247

248248
use super::*;
249-
use crate::NSValue;
249+
use crate::{NSString, NSValue};
250250

251251
fn sample_array(len: usize) -> Id<NSArray<NSObject, Owned>, Owned> {
252252
let mut vec = Vec::with_capacity(len);
@@ -374,4 +374,19 @@ mod tests {
374374
let vec = NSArray::into_vec(array);
375375
assert_eq!(vec.len(), 4);
376376
}
377+
378+
#[test]
379+
fn test_generic_ownership_traits() {
380+
fn assert_partialeq<T: PartialEq>() {}
381+
382+
assert_partialeq::<NSArray<NSString, Shared>>();
383+
assert_partialeq::<NSArray<NSString, Owned>>();
384+
385+
fn test_ownership_implies_partialeq<O: Ownership>() {
386+
assert_partialeq::<NSArray<NSString, O>>();
387+
}
388+
389+
test_ownership_implies_partialeq::<Shared>();
390+
test_ownership_implies_partialeq::<Owned>();
391+
}
377392
}

objc2/src/rc/ownership.rs

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
1+
use core::fmt::Debug;
2+
use core::hash::Hash;
3+
use core::panic::{RefUnwindSafe, UnwindSafe};
4+
5+
use super::AutoreleaseSafe;
6+
7+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
8+
enum Never {}
9+
110
/// A type used to mark that a struct owns the object(s) it contains,
211
/// so it has the sole references to them.
312
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
4-
pub enum Owned {}
13+
pub struct Owned {
14+
inner: Never,
15+
}
516

617
/// A type used to mark that the object(s) a struct contains are shared,
718
/// so there may be other references to them.
819
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
9-
pub enum Shared {}
20+
pub struct Shared {
21+
inner: Never,
22+
}
1023

1124
mod private {
1225
pub trait Sealed {}
@@ -20,7 +33,50 @@ mod private {
2033
///
2134
/// This trait is sealed and not meant to be implemented outside of the this
2235
/// crate.
23-
pub trait Ownership: private::Sealed + 'static {}
36+
pub trait Ownership:
37+
private::Sealed
38+
// Special
39+
+ 'static
40+
+ Sized
41+
// Auto-traits
42+
+ Send
43+
+ Sync
44+
+ Unpin
45+
+ UnwindSafe
46+
+ RefUnwindSafe
47+
// Derived
48+
+ Clone
49+
+ Copy
50+
+ PartialEq
51+
+ Eq
52+
+ PartialOrd
53+
+ Ord
54+
+ Hash
55+
+ Debug
56+
// Custom
57+
+ AutoreleaseSafe
58+
{
59+
}
2460

2561
impl Ownership for Owned {}
2662
impl Ownership for Shared {}
63+
64+
#[cfg(test)]
65+
mod tests {
66+
use super::*;
67+
68+
#[test]
69+
fn test_generic_ownership_traits() {
70+
fn assert_partialeq<T: PartialEq>() {}
71+
72+
assert_partialeq::<Shared>();
73+
assert_partialeq::<Owned>();
74+
75+
fn test_ownership_implies_partialeq<O: Ownership>() {
76+
assert_partialeq::<O>();
77+
}
78+
79+
test_ownership_implies_partialeq::<Shared>();
80+
test_ownership_implies_partialeq::<Owned>();
81+
}
82+
}

test-ui/ui/msg_send_id_invalid_return.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ error[E0308]: mismatched types
100100
--> ui/msg_send_id_invalid_return.rs
101101
|
102102
| let _: Id<Object, Owned> = unsafe { msg_send_id![obj, init].unwrap() };
103-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `objc2::rc::Owned`, found enum `Shared`
103+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `objc2::rc::Owned`, found struct `Shared`
104104
|
105105
= note: expected struct `Id<_, objc2::rc::Owned>`
106106
found struct `Id<_, Shared>`

test-ui/ui/msg_send_id_underspecified.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
error[E0282]: type annotations needed for `Option<Id<objc2::runtime::Object, O>>`
1+
error[E0283]: type annotations needed for `Option<Id<objc2::runtime::Object, O>>`
22
--> ui/msg_send_id_underspecified.rs
33
|
44
| let _: &Object = &*unsafe { msg_send_id![obj, description].unwrap() };
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type must be known at this point
66
|
7+
= note: cannot satisfy `_: Ownership`
8+
= note: required because of the requirements on the impl of `MsgSendId<&objc2::runtime::Object, Id<objc2::runtime::Object, _>>` for `RetainSemantics<false, false, false, false>`
79
= note: this error originates in the macro `msg_send_id` (in Nightly builds, run with -Z macro-backtrace for more info)
810
help: consider giving `result` an explicit type, where the type for type parameter `O` is specified
911
--> $WORKSPACE/objc2/src/macros.rs

0 commit comments

Comments
 (0)