Skip to content

Commit 996f48b

Browse files
committed
Add unstable-extern-types feature
1 parent 01f8bf4 commit 996f48b

File tree

10 files changed

+56
-30
lines changed

10 files changed

+56
-30
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ jobs:
153153
TESTARGS: ${{ matrix.dinghy && ' ' || '--no-fail-fast' }} ${{ matrix.test-args }}
154154
SOME_FEATURES: ${{ matrix.features || 'malloc,block,exception,foundation' }}
155155
FEATURES: ${{ matrix.features || 'malloc,block,exception,foundation,catch-all,verify_message,uuid' }}
156-
UNSTABLE_FEATURES: ${{ matrix.unstable-features || 'unstable-autoreleasesafe,unstable-c-unwind' }}
156+
UNSTABLE_FEATURES: ${{ matrix.unstable-features || 'unstable-autoreleasesafe,unstable-c-unwind,unstable-extern-types' }}
157157
CMD: cargo
158158

159159
runs-on: ${{ matrix.os }}

objc-sys/Cargo.toml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,26 +33,29 @@ default = ["std", "apple"]
3333
std = ["alloc"]
3434
alloc = []
3535

36-
# Link to Apple's objc4
36+
# Link to Apple's objc4.
3737
apple = []
3838

39-
# Link to GNUStep's libobjc2
39+
# Link to GNUStep's libobjc2.
4040
gnustep-1-7 = []
4141
gnustep-1-8 = ["gnustep-1-7"]
4242
gnustep-1-9 = ["gnustep-1-8"]
4343
gnustep-2-0 = ["gnustep-1-9"]
4444
gnustep-2-1 = ["gnustep-2-0"]
4545

46-
# Link to Microsoft's libobjc2
46+
# Link to Microsoft's libobjc2.
4747
unstable-winobjc = ["gnustep-1-8"]
4848

49-
# Link to ObjFW
49+
# Link to ObjFW.
5050
unstable-objfw = []
5151

52-
# Use nightly c_unwind feature
52+
# Use nightly c_unwind feature.
5353
unstable-c-unwind = []
5454

55-
# Private
55+
# Use nightly extern_types feature to mark opaque types as !Sized.
56+
unstable-extern-types = []
57+
58+
# Private.
5659
unstable-exception = ["cc"]
5760
unstable-docsrs = []
5861

objc-sys/src/lib.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#![cfg_attr(feature = "unstable-c-unwind", feature(c_unwind))]
2929
#![cfg_attr(feature = "unstable-docsrs", feature(doc_auto_cfg, doc_cfg_hide))]
3030
#![cfg_attr(feature = "unstable-docsrs", doc(cfg_hide(doc)))]
31+
#![cfg_attr(feature = "unstable-extern-types", feature(extern_types))]
3132

3233
// TODO: Remove this and add "no-std" category to Cargo.toml
3334
// Requires a better solution for C-types in `no_std` crates.
@@ -41,9 +42,6 @@ compile_error!("The `std` feature currently must be enabled.");
4142
#[doc = include_str!("../README.md")]
4243
extern "C" {}
4344

44-
use core::cell::UnsafeCell;
45-
use core::marker::{PhantomData, PhantomPinned};
46-
4745
macro_rules! generate_linking_tests {
4846
{
4947
extern $abi:literal {$(
@@ -170,9 +168,18 @@ pub use various::*;
170168
///
171169
/// Downstream libraries can always manually opt in to these types afterwards.
172170
/// (It's also less of a breaking change on our part if we re-add these).
173-
///
174-
/// TODO: Replace this with `extern type` to also mark it as `!Sized`.
175-
type OpaqueData = UnsafeCell<PhantomData<(*const UnsafeCell<()>, PhantomPinned)>>;
171+
#[cfg(not(feature = "unstable-extern-types"))]
172+
type OpaqueData = core::cell::UnsafeCell<
173+
core::marker::PhantomData<(
174+
*const core::cell::UnsafeCell<()>,
175+
core::marker::PhantomPinned,
176+
)>,
177+
>;
178+
179+
#[cfg(feature = "unstable-extern-types")]
180+
extern "C" {
181+
type OpaqueData;
182+
}
176183

177184
#[cfg(test)]
178185
mod tests {

objc2/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1616
* **BREAKING**: Added required `ClassType::NAME` constant for statically
1717
determining the name of a specific class.
1818
* Allow directly specifying class name in declare_class! macro.
19+
* Added the `"unstable-extern-types"` feature flags to make relevant types
20+
`!Sized`.
1921

2022
### Changed
2123
* **BREAKING**: Slightly changed when a type implements `?Sized` to support

objc2/Cargo.toml

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ malloc = ["malloc_buf"]
4747
# Expose features that requires creating blocks.
4848
block = ["block2"]
4949

50+
# Runtime selection. See `objc-sys` for details.
51+
apple = ["objc-sys/apple", "objc2-encode/apple", "block2?/apple"]
52+
gnustep-1-7 = ["objc-sys/gnustep-1-7", "objc2-encode/gnustep-1-7", "block2?/gnustep-1-7"]
53+
gnustep-1-8 = ["gnustep-1-7", "objc-sys/gnustep-1-8", "objc2-encode/gnustep-1-8", "block2?/gnustep-1-8"]
54+
gnustep-1-9 = ["gnustep-1-8", "objc-sys/gnustep-1-9", "objc2-encode/gnustep-1-9", "block2?/gnustep-1-9"]
55+
gnustep-2-0 = ["gnustep-1-9", "objc-sys/gnustep-2-0", "objc2-encode/gnustep-2-0", "block2?/gnustep-2-0"]
56+
gnustep-2-1 = ["gnustep-2-0", "objc-sys/gnustep-2-1", "objc2-encode/gnustep-2-1", "block2?/gnustep-2-1"]
57+
5058
# Make the `sel!` macro look up the selector statically.
5159
#
5260
# The plan is to enable this by default, but right now we are uncertain of
@@ -69,16 +77,13 @@ unstable-autoreleasesafe = []
6977
# `objc2-encode/unstable-c-unwind` to use this.
7078
unstable-c-unwind = []
7179

72-
# For better documentation on docs.rs
73-
unstable-docsrs = []
80+
# Use nightly features to make Object and other types !Sized.
81+
#
82+
# You must manually enable `objc-sys/unstable-extern-types` to use this.
83+
unstable-extern-types = []
7484

75-
# Runtime selection. See `objc-sys` for details.
76-
apple = ["objc-sys/apple", "objc2-encode/apple", "block2?/apple"]
77-
gnustep-1-7 = ["objc-sys/gnustep-1-7", "objc2-encode/gnustep-1-7", "block2?/gnustep-1-7"]
78-
gnustep-1-8 = ["gnustep-1-7", "objc-sys/gnustep-1-8", "objc2-encode/gnustep-1-8", "block2?/gnustep-1-8"]
79-
gnustep-1-9 = ["gnustep-1-8", "objc-sys/gnustep-1-9", "objc2-encode/gnustep-1-9", "block2?/gnustep-1-9"]
80-
gnustep-2-0 = ["gnustep-1-9", "objc-sys/gnustep-2-0", "objc2-encode/gnustep-2-0", "block2?/gnustep-2-0"]
81-
gnustep-2-1 = ["gnustep-2-0", "objc-sys/gnustep-2-1", "objc2-encode/gnustep-2-1", "block2?/gnustep-2-1"]
85+
# Private.
86+
unstable-docsrs = []
8287

8388
[dependencies]
8489
malloc_buf = { version = "1.0", optional = true }

objc2/src/cache.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use core::ffi::c_void;
12
use core::ptr;
23
use core::sync::atomic::{AtomicPtr, Ordering};
34

@@ -7,7 +8,7 @@ use crate::runtime::{Class, Sel};
78
/// Allows storing a [`Sel`] in a static and lazily loading it.
89
#[doc(hidden)]
910
pub struct CachedSel {
10-
ptr: AtomicPtr<ffi::objc_selector>,
11+
ptr: AtomicPtr<c_void>,
1112
}
1213

1314
impl CachedSel {
@@ -24,7 +25,7 @@ impl CachedSel {
2425
#[doc(hidden)]
2526
pub unsafe fn get(&self, name: &str) -> Sel {
2627
// `Relaxed` should be fine since `sel_registerName` is thread-safe.
27-
let ptr = self.ptr.load(Ordering::Relaxed);
28+
let ptr: *const ffi::objc_selector = self.ptr.load(Ordering::Relaxed).cast();
2829
unsafe { Sel::from_ptr(ptr) }.unwrap_or_else(|| {
2930
// The panic inside `Sel::register_unchecked` is unfortunate, but
3031
// strict correctness is more important than speed
@@ -34,7 +35,7 @@ impl CachedSel {
3435
// We know this, because we construct it in `sel!` ourselves
3536
let sel = unsafe { Sel::register_unchecked(name.as_ptr().cast()) };
3637
self.ptr
37-
.store(sel.as_ptr() as *mut ffi::objc_selector, Ordering::Relaxed);
38+
.store(sel.as_ptr() as *mut c_void, Ordering::Relaxed);
3839
sel
3940
})
4041
}
@@ -43,7 +44,7 @@ impl CachedSel {
4344
/// Allows storing a [`Class`] reference in a static and lazily loading it.
4445
#[doc(hidden)]
4546
pub struct CachedClass {
46-
ptr: AtomicPtr<Class>,
47+
ptr: AtomicPtr<c_void>,
4748
}
4849

4950
impl CachedClass {
@@ -60,12 +61,12 @@ impl CachedClass {
6061
#[doc(hidden)]
6162
pub unsafe fn get(&self, name: &str) -> Option<&'static Class> {
6263
// `Relaxed` should be fine since `objc_getClass` is thread-safe.
63-
let ptr = self.ptr.load(Ordering::Relaxed);
64+
let ptr: *const Class = self.ptr.load(Ordering::Relaxed).cast();
6465
if let Some(cls) = unsafe { ptr.as_ref() } {
6566
Some(cls)
6667
} else {
6768
let ptr: *const Class = unsafe { ffi::objc_getClass(name.as_ptr().cast()) }.cast();
68-
self.ptr.store(ptr as *mut Class, Ordering::Relaxed);
69+
self.ptr.store(ptr as *mut c_void, Ordering::Relaxed);
6970
unsafe { ptr.as_ref() }
7071
}
7172
}

objc2/src/foundation/array.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ __inner_extern_class!(
6363
);
6464

6565
// SAFETY: Same as Id<T, O> (which is what NSArray effectively stores).
66+
//
67+
// Duplicated here, rustdoc doesn't show these otherwise.
6668
unsafe impl<T: ?Sized + Message + Sync + Send> Sync for NSArray<T, Shared> {}
6769
unsafe impl<T: ?Sized + Message + Sync + Send> Send for NSArray<T, Shared> {}
6870
unsafe impl<T: ?Sized + Message + Sync> Sync for NSArray<T, Owned> {}

objc2/src/foundation/mutable_array.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ __inner_extern_class!(
3535

3636
// SAFETY: Same as NSArray<T, O>
3737
//
38-
// Put here because rustdoc doesn't show these otherwise
38+
// Duplicated here, rustdoc doesn't show these otherwise.
3939
unsafe impl<T: ?Sized + Message + Sync + Send> Sync for NSMutableArray<T, Shared> {}
4040
unsafe impl<T: ?Sized + Message + Sync + Send> Send for NSMutableArray<T, Shared> {}
4141
unsafe impl<T: ?Sized + Message + Sync> Sync for NSMutableArray<T, Owned> {}

objc2/src/foundation/set.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ __inner_extern_class!(
2828
}
2929
);
3030

31-
// SAFETY: Same as NSArray<T, O>
31+
// SAFETY: Same as Id<T, O>.
32+
//
33+
// Duplicated here, rustdoc doesn't show these otherwise.
3234
unsafe impl<T: ?Sized + Message + Sync + Send> Sync for NSSet<T, Shared> {}
3335
unsafe impl<T: ?Sized + Message + Sync + Send> Send for NSSet<T, Shared> {}
3436
unsafe impl<T: ?Sized + Message + Sync> Sync for NSSet<T, Owned> {}

objc2/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@
167167
)]
168168
#![cfg_attr(feature = "unstable-c-unwind", feature(c_unwind))]
169169
#![cfg_attr(feature = "unstable-docsrs", feature(doc_auto_cfg))]
170+
#![cfg_attr(feature = "unstable-extern-types", feature(extern_types, ptr_metadata))]
170171
#![warn(elided_lifetimes_in_paths)]
171172
#![warn(missing_docs)]
172173
#![deny(non_ascii_idents)]
@@ -186,7 +187,10 @@ compile_error!("The `std` feature currently must be enabled.");
186187
extern crate alloc;
187188
extern crate std;
188189

190+
#[cfg(not(feature = "unstable-extern-types"))]
189191
pub(crate) use core::marker::Sized as Thin;
192+
#[cfg(feature = "unstable-extern-types")]
193+
pub(crate) use core::ptr::Thin;
190194

191195
// The example uses NSObject without doing the __gnustep_hack
192196
#[cfg(all(feature = "apple", doctest))]

0 commit comments

Comments
 (0)