Skip to content

Commit 7a3cb1f

Browse files
authored
Merge pull request #94 from madsmtm/send-sync-fixes
`Send` and `Sync` fixes
2 parents b47508f + e478974 commit 7a3cb1f

File tree

15 files changed

+192
-14
lines changed

15 files changed

+192
-14
lines changed

block-sys/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66

77
## Unreleased - YYYY-MM-DD
88

9+
### Fixed
10+
* **BREAKING**: `Class` is now `!UnwindSafe`.
911

1012
## 0.0.1 - 2021-11-22
1113

block-sys/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub struct Class {
3434
_priv: [u8; 0],
3535

3636
/// See objc_sys::OpaqueData
37-
_opaque: PhantomData<(UnsafeCell<*const ()>, PhantomPinned)>,
37+
_opaque: PhantomData<(UnsafeCell<()>, *const UnsafeCell<()>, PhantomPinned)>,
3838
}
3939

4040
/// Block descriptor flags.

objc-sys/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1919
present on other platforms anyhow, so users will just get an error at
2020
link-time.
2121

22+
### Fixed
23+
* **BREAKING**: Opaque types are now also `!UnwindSafe`.
24+
2225

2326
## 0.1.0 - 2021-11-22
2427

objc-sys/src/lib.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,11 @@ pub use types::*;
5656
pub use various::*;
5757

5858
/// We don't know much about the actual structs, so better mark them `!Send`,
59-
/// `!Sync`, `!Unpin` and as mutable behind shared references. Downstream
60-
/// libraries can always manually opt in to these types afterwards. (It's
61-
/// also less of a breaking change on our part if we re-add these later).
59+
/// `!Sync`, `!UnwindSafe`, `!RefUnwindSafe`, `!Unpin` and as mutable behind
60+
/// shared references.
6261
///
63-
/// TODO: Replace this with `extern type` to also mark it as unsized.
64-
type OpaqueData = PhantomData<(UnsafeCell<*const ()>, PhantomPinned)>;
62+
/// Downstream libraries can always manually opt in to these types afterwards.
63+
/// (It's also less of a breaking change on our part if we re-add these).
64+
///
65+
/// TODO: Replace this with `extern type` to also mark it as `!Sized`.
66+
type OpaqueData = PhantomData<(UnsafeCell<()>, *const UnsafeCell<()>, PhantomPinned)>;

objc2-foundation/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
2525
### Fixed
2626
* Soundness issue with `NSValue`, `NSDictionary`, `NSArray` and
2727
`NSMutableArray` not being `#[repr(C)]`.
28+
* **BREAKING**: `NSObject` is no longer `Send` and `Sync` (because its
29+
subclasses may not be).
2830

2931
## 0.2.0-alpha.2 - 2021-11-22
3032

objc2-foundation/src/array.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,26 @@ object!(
174174
}
175175
);
176176

177+
// SAFETY: Same as Id<T, O> (which is what NSArray effectively stores).
178+
//
179+
// The `PhantomData` can't get these impls to display in the docs.
180+
//
181+
// TODO: Properly verify this
182+
unsafe impl<T: Sync + Send> Sync for NSArray<T, Shared> {}
183+
unsafe impl<T: Sync + Send> Send for NSArray<T, Shared> {}
184+
unsafe impl<T: Sync> Sync for NSArray<T, Owned> {}
185+
unsafe impl<T: Send> Send for NSArray<T, Owned> {}
186+
187+
/// ```compile_fail
188+
/// use objc2::rc::Shared;
189+
/// use objc2::runtime::Object;
190+
/// use objc2_foundation::NSArray;
191+
/// fn needs_send_sync<T: Send + Sync>() {}
192+
/// needs_send_sync::<NSArray<Object, Shared>>();
193+
/// ```
194+
#[cfg(doctest)]
195+
pub struct NSArrayWithObjectNotSendSync;
196+
177197
unsafe impl<T: INSObject, O: Ownership> INSArray for NSArray<T, O> {
178198
/// The `NSArray` itself (length and number of items) is always immutable,
179199
/// but we would like to know when we're the only owner of the array, to
@@ -319,6 +339,14 @@ object!(
319339
}
320340
);
321341

342+
// SAFETY: Same as NSArray.
343+
//
344+
// TODO: Properly verify this
345+
unsafe impl<T: Sync + Send> Sync for NSMutableArray<T, Shared> {}
346+
unsafe impl<T: Sync + Send> Send for NSMutableArray<T, Shared> {}
347+
unsafe impl<T: Sync> Sync for NSMutableArray<T, Owned> {}
348+
unsafe impl<T: Send> Send for NSMutableArray<T, Owned> {}
349+
322350
unsafe impl<T: INSObject, O: Ownership> INSArray for NSMutableArray<T, O> {
323351
type Ownership = Owned;
324352
type Item = T;
@@ -540,4 +568,14 @@ mod tests {
540568
assert_eq!(strings[1].as_str(pool), "hello");
541569
});
542570
}
571+
572+
#[test]
573+
fn test_send_sync() {
574+
fn assert_send_sync<T: Send + Sync>() {}
575+
576+
assert_send_sync::<NSArray<NSString, Shared>>();
577+
assert_send_sync::<NSMutableArray<NSString, Shared>>();
578+
assert_send_sync::<Id<NSArray<NSString, Shared>, Shared>>();
579+
assert_send_sync::<Id<NSMutableArray<NSString, Shared>, Owned>>();
580+
}
543581
}

objc2-foundation/src/data.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ pub unsafe trait INSData: INSObject {
9494

9595
object!(unsafe pub struct NSData);
9696

97+
// TODO: SAFETY
98+
unsafe impl Sync for NSData {}
99+
unsafe impl Send for NSData {}
100+
97101
unsafe impl INSData for NSData {
98102
type Ownership = Shared;
99103
}
@@ -157,6 +161,10 @@ pub unsafe trait INSMutableData: INSData {
157161

158162
object!(unsafe pub struct NSMutableData);
159163

164+
// TODO: SAFETY
165+
unsafe impl Sync for NSMutableData {}
166+
unsafe impl Send for NSMutableData {}
167+
160168
unsafe impl INSData for NSMutableData {
161169
type Ownership = Owned;
162170
}

objc2-foundation/src/dictionary.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ object!(
145145
}
146146
);
147147

148+
// TODO: SAFETY
149+
unsafe impl<K: Sync + Send, V: Sync> Sync for NSDictionary<K, V> {}
150+
unsafe impl<K: Sync + Send, V: Send> Send for NSDictionary<K, V> {}
151+
148152
impl<K: INSObject, V: INSObject> NSDictionary<K, V> {
149153
unsafe_def_fn!(pub fn new -> Shared);
150154
}

objc2-foundation/src/object.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
use core::marker::PhantomData;
12
use core::ptr::NonNull;
23

34
use objc2::msg_send;
45
use objc2::rc::{Id, Owned, Shared};
5-
use objc2::runtime::{Bool, Class};
6+
use objc2::runtime::{Bool, Class, Object};
67
use objc2::Message;
78

89
use super::NSString;
@@ -37,7 +38,22 @@ pub unsafe trait INSObject: Sized + Message {
3738
}
3839
}
3940

40-
object!(unsafe pub struct NSObject);
41+
object!(unsafe pub struct NSObject<> {
42+
p: PhantomData<Object>, // Temporary
43+
});
44+
45+
/// ```compile_fail
46+
/// use objc2_foundation::NSObject;
47+
/// fn needs_sync<T: Sync>() {}
48+
/// needs_sync::<NSObject>();
49+
/// ```
50+
/// ```compile_fail
51+
/// use objc2_foundation::NSObject;
52+
/// fn needs_send<T: Send>() {}
53+
/// needs_send::<NSObject>();
54+
/// ```
55+
#[cfg(doctest)]
56+
pub struct NSObjectNotSendNorSync;
4157

4258
impl NSObject {
4359
unsafe_def_fn!(pub fn new -> Owned);

objc2-foundation/src/string.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ pub unsafe trait INSString: INSObject {
102102

103103
object!(unsafe pub struct NSString);
104104

105+
// TODO: SAFETY
106+
unsafe impl Sync for NSString {}
107+
unsafe impl Send for NSString {}
108+
105109
impl NSString {
106110
unsafe_def_fn!(pub fn new -> Shared);
107111
}

0 commit comments

Comments
 (0)