Skip to content

Commit 4a073e0

Browse files
committed
Properly test Send and Sync in objc2-foundation
1 parent d77a94b commit 4a073e0

File tree

11 files changed

+68
-27
lines changed

11 files changed

+68
-27
lines changed

objc2-foundation/src/array.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ __inner_extern_class! {
3333

3434
// SAFETY: Same as Id<T, O> (which is what NSArray effectively stores).
3535
//
36-
// The `PhantomData` can't get these impls to display in the docs.
37-
//
3836
// TODO: Properly verify this
3937
unsafe impl<T: Sync + Send> Sync for NSArray<T, Shared> {}
4038
unsafe impl<T: Sync + Send> Send for NSArray<T, Shared> {}
@@ -218,7 +216,7 @@ mod tests {
218216
use objc2::rc::autoreleasepool;
219217

220218
use super::*;
221-
use crate::{NSString, NSValue};
219+
use crate::NSValue;
222220

223221
fn sample_array(len: usize) -> Id<NSArray<NSObject, Owned>, Owned> {
224222
let mut vec = Vec::with_capacity(len);
@@ -350,14 +348,4 @@ mod tests {
350348
let vec = NSArray::into_vec(array);
351349
assert_eq!(vec.len(), 4);
352350
}
353-
354-
#[test]
355-
fn test_send_sync() {
356-
fn assert_send_sync<T: Send + Sync>() {}
357-
358-
assert_send_sync::<NSArray<NSString, Shared>>();
359-
assert_send_sync::<NSMutableArray<NSString, Shared>>();
360-
assert_send_sync::<Id<NSArray<NSString, Shared>, Shared>>();
361-
assert_send_sync::<Id<NSMutableArray<NSString, Shared>, Owned>>();
362-
}
363351
}

objc2-foundation/src/attributed_string.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ extern_class! {
2424
unsafe pub struct NSAttributedString: NSObject;
2525
}
2626

27-
// TODO: SAFETY
27+
// SAFETY: `NSAttributedString` is immutable and `NSMutableAttributedString`
28+
// can only be mutated from `&mut` methods.
2829
unsafe impl Sync for NSAttributedString {}
2930
unsafe impl Send for NSAttributedString {}
3031

objc2-foundation/src/data.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ extern_class! {
2020
unsafe pub struct NSData: NSObject;
2121
}
2222

23-
// TODO: SAFETY
23+
// SAFETY: `NSData` is immutable and `NSMutableData` can only be mutated from
24+
// `&mut` methods.
2425
unsafe impl Sync for NSData {}
2526
unsafe impl Send for NSData {}
2627

objc2-foundation/src/dictionary.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ __inner_extern_class! {
1818
}
1919

2020
// TODO: SAFETY
21+
// Approximately same as `NSArray<T, Shared>`
2122
unsafe impl<K: Sync + Send, V: Sync> Sync for NSDictionary<K, V> {}
2223
unsafe impl<K: Sync + Send, V: Send> Send for NSDictionary<K, V> {}
2324

objc2-foundation/src/lib.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,48 @@ mod thread;
115115
mod uuid;
116116
mod value;
117117
mod zone;
118+
119+
#[cfg(test)]
120+
mod tests {
121+
use objc2::rc::{Id, Owned, Shared};
122+
123+
use super::*;
124+
125+
fn assert_send_sync<T: Send + Sync>() {}
126+
127+
#[test]
128+
fn send_sync() {
129+
assert_send_sync::<NSArray<NSString, Shared>>();
130+
assert_send_sync::<NSArray<NSString, Owned>>();
131+
assert_send_sync::<Id<NSArray<NSString, Shared>, Shared>>();
132+
assert_send_sync::<Id<NSArray<NSString, Owned>, Shared>>();
133+
assert_send_sync::<Id<NSArray<NSString, Shared>, Owned>>();
134+
assert_send_sync::<Id<NSArray<NSString, Owned>, Owned>>();
135+
136+
assert_send_sync::<NSAttributedString>();
137+
assert_send_sync::<NSComparisonResult>();
138+
assert_send_sync::<NSData>();
139+
assert_send_sync::<NSDictionary<NSString, Shared>>();
140+
// TODO: Figure out if safe?
141+
// assert_send_sync::<NSEnumerator<NSString>>();
142+
// assert_send_sync::<NSFastEnumerator<NSArray<NSString, Shared>>>();
143+
assert_send_sync::<NSException>();
144+
assert_send_sync::<CGFloat>();
145+
assert_send_sync::<NSPoint>();
146+
assert_send_sync::<NSRect>();
147+
assert_send_sync::<NSSize>();
148+
assert_send_sync::<NSMutableArray<NSString, Shared>>();
149+
assert_send_sync::<NSMutableAttributedString>();
150+
assert_send_sync::<NSMutableData>();
151+
assert_send_sync::<NSMutableString>();
152+
// assert_send_sync::<NSObject>(); // Intentional
153+
assert_send_sync::<NSProcessInfo>();
154+
assert_send_sync::<NSRange>();
155+
assert_send_sync::<NSString>();
156+
// assert_send_sync::<MainThreadMarker>(); // Intentional
157+
assert_send_sync::<NSThread>();
158+
assert_send_sync::<NSUUID>();
159+
assert_send_sync::<NSValue<i32>>();
160+
assert_send_sync::<NSZone>();
161+
}
162+
}

objc2-foundation/src/mutable_array.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use alloc::vec::Vec;
22
use core::cmp::Ordering;
33
use core::ffi::c_void;
4+
use core::marker::PhantomData;
45
use core::ops::{Index, IndexMut};
56

67
use objc2::rc::{DefaultId, Id, Owned, Ownership, Shared, SliceId};
@@ -17,9 +18,19 @@ __inner_extern_class! {
1718
// TODO: Ensure that this deref to NSArray is safe!
1819
// This "inherits" NSArray, and has the same `Send`/`Sync` impls as that.
1920
#[derive(Debug, PartialEq, Eq, Hash)]
20-
unsafe pub struct NSMutableArray<T, O: Ownership>: NSArray<T, O>, NSObject {}
21+
unsafe pub struct NSMutableArray<T, O: Ownership>: NSArray<T, O>, NSObject {
22+
p: PhantomData<*mut ()>,
23+
}
2124
}
2225

26+
// SAFETY: Same as NSArray<T, O>
27+
//
28+
// Put here because rustdoc doesn't show these otherwise
29+
unsafe impl<T: Sync + Send> Sync for NSMutableArray<T, Shared> {}
30+
unsafe impl<T: Sync + Send> Send for NSMutableArray<T, Shared> {}
31+
unsafe impl<T: Sync> Sync for NSMutableArray<T, Owned> {}
32+
unsafe impl<T: Send> Send for NSMutableArray<T, Owned> {}
33+
2334
impl<T: Message, O: Ownership> NSMutableArray<T, O> {
2435
pub fn new() -> Id<Self, Owned> {
2536
unsafe { msg_send_id![Self::class(), new].unwrap() }

objc2-foundation/src/mutable_attributed_string.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ extern_class! {
1111
unsafe pub struct NSMutableAttributedString: NSAttributedString, NSObject;
1212
}
1313

14-
// TODO: SAFETY
15-
unsafe impl Sync for NSMutableAttributedString {}
16-
unsafe impl Send for NSMutableAttributedString {}
17-
1814
/// Creating mutable attributed strings.
1915
impl NSMutableAttributedString {
2016
/// Construct an empty mutable attributed string.

objc2-foundation/src/mutable_string.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ extern_class! {
1616
unsafe pub struct NSMutableString: NSString, NSObject;
1717
}
1818

19-
// TODO: SAFETY
20-
unsafe impl Sync for NSMutableString {}
21-
unsafe impl Send for NSMutableString {}
22-
2319
/// Creating mutable strings.
2420
impl NSMutableString {
2521
/// Construct an empty [`NSMutableString`].

objc2-foundation/src/string.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ extern_class! {
4141
// TODO: Check if performance of NSSelectorFromString is worthwhile
4242
}
4343

44-
// TODO: SAFETY
44+
// SAFETY: `NSString` is immutable and `NSMutableString` can only be mutated
45+
// from `&mut` methods.
4546
unsafe impl Sync for NSString {}
4647
unsafe impl Send for NSString {}
4748

objc2-foundation/src/uuid.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ unsafe impl RefEncode for UuidBytes {
2525
const ENCODING_REF: Encoding<'static> = Encoding::Array(16, &u8::ENCODING);
2626
}
2727

28-
// TODO: SAFETY
28+
// SAFETY: `NSUUID` is immutable.
2929
unsafe impl Sync for NSUUID {}
3030
unsafe impl Send for NSUUID {}
3131

0 commit comments

Comments
 (0)