Skip to content

Commit 3478b6f

Browse files
jbatezmadsmtm
authored andcommitted
add the unstable-darwin-objc feature
1 parent cefedf4 commit 3478b6f

File tree

390 files changed

+489
-17
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

390 files changed

+489
-17
lines changed

crates/header-translator/src/library.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,12 @@ impl Library {
232232
)?;
233233
writeln!(lib_rs, "//! [framework-crates]: https://docs.rs/objc2/latest/objc2/topics/about_generated/index.html")?;
234234
writeln!(lib_rs, "#![no_std]")?;
235+
if !self.data.is_library {
236+
writeln!(
237+
lib_rs,
238+
"#![cfg_attr(feature = \"unstable-darwin-objc\", feature(darwin_objc))]"
239+
)?;
240+
}
235241
writeln!(lib_rs, "#![cfg_attr(docsrs, feature(doc_auto_cfg))]")?;
236242
writeln!(lib_rs, "// Update in Cargo.toml as well.")?;
237243
writeln!(
@@ -447,6 +453,20 @@ see that for related crates.", self.data.krate)?;
447453
cargo_toml["features"][feature] = array_with_newlines(enabled_features);
448454
}
449455

456+
// Emit unstable-darwin-objc feature in framework crates.
457+
//
458+
// We could also use this to enable the feature automatically in
459+
// dependencies, but we'd like for this feature to remain "unstable" in
460+
// the sense that we'd be free to remove it in a patch release. By
461+
// mentioning it across crates, that would no longer be the case.
462+
//
463+
// It's slightly less convenient for users, but in practice, most users
464+
// already directly depend on all their `objc2-*` crates in their
465+
// dependency tree.
466+
if !self.data.is_library {
467+
cargo_toml["features"]["unstable-darwin-objc"] = array_with_newlines([]);
468+
}
469+
450470
// And then the rest of the features.
451471
if !emitted_features.is_empty() {
452472
add_newline_at_end(&mut cargo_toml["features"]);

crates/objc2/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ verify = []
8080
#
8181
# Please test it, and report any issues you may find:
8282
# https://github.com/madsmtm/objc2/issues/new
83+
unstable-darwin-objc = []
8384
unstable-static-sel = ["dep:objc2-proc-macros"]
8485
unstable-static-sel-inlined = ["unstable-static-sel"]
8586
unstable-static-class = ["dep:objc2-proc-macros"]

crates/objc2/src/__macros/class.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ use crate::runtime::AnyClass;
2727
///
2828
/// # Features
2929
///
30-
/// If the experimental `"unstable-static-class"` feature is enabled, this
31-
/// will emit special statics that will be replaced by dyld when the program
32-
/// starts up.
30+
/// If the experimental `"unstable-static-class"` or `"unstable-darwin-objc"`
31+
/// features are enabled, this will emit special statics that will be replaced
32+
/// by dyld when the program starts up.
3333
///
3434
/// Errors that were previously runtime panics may now turn into linker errors
3535
/// if you try to use a class which is not available. Additionally, you may
@@ -78,7 +78,10 @@ macro_rules! class {
7878

7979
#[doc(hidden)]
8080
#[macro_export]
81-
#[cfg(not(feature = "unstable-static-class"))]
81+
#[cfg(not(any(
82+
feature = "unstable-darwin-objc",
83+
feature = "unstable-static-class"
84+
)))]
8285
macro_rules! __class_inner {
8386
($name:expr, $_hash:expr) => {{
8487
static CACHED_CLASS: $crate::__macros::CachedClass = $crate::__macros::CachedClass::new();
@@ -89,6 +92,22 @@ macro_rules! __class_inner {
8992
}};
9093
}
9194

95+
#[doc(hidden)]
96+
#[macro_export]
97+
#[cfg(all(
98+
feature = "unstable-darwin-objc",
99+
not(feature = "unstable-static-class")
100+
))]
101+
macro_rules! __class_inner {
102+
($name:expr, $_hash:expr) => {{
103+
let ptr = $crate::__macros::core_darwin_objc::class!($name);
104+
let ptr = ptr.cast_const().cast::<$crate::runtime::AnyClass>();
105+
#[allow(unused_unsafe)]
106+
let r: &'static $crate::runtime::AnyClass = unsafe { &*ptr };
107+
r
108+
}};
109+
}
110+
92111
#[doc(hidden)]
93112
#[macro_export]
94113
#[cfg(all(

crates/objc2/src/__macros/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ pub use core::primitive::{bool, isize, str, u8};
5252
pub use core::{compile_error, concat, env, module_path, panic, stringify};
5353
pub use std::sync::Once;
5454

55+
#[cfg(feature = "unstable-darwin-objc")]
56+
pub use core::os::darwin::objc as core_darwin_objc;
57+
5558
pub use self::available::{is_available, AvailableVersion, OSVersion};
5659
pub use self::class::{disallow_in_static, CachedClass};
5760
pub use self::convert::{ConvertArgument, ConvertArguments, ConvertReturn, TupleExtender};

crates/objc2/src/__macros/sel.rs

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,29 @@ use crate::runtime::Sel;
4949
/// - runtime, causing UB (unlikely)
5050
///
5151
/// The `"unstable-static-sel-inlined"` feature is the even more extreme
52-
/// version - it yields the best performance and is closest to real
52+
/// version - it yield better performance and is closer to real
5353
/// Objective-C code, but probably won't work unless your code and its
5454
/// inlining is written in a very certain way.
5555
///
5656
/// Enabling LTO greatly increases the chance that these features work.
5757
///
58+
/// On Apple/Darwin targets, these limitations can be overcome with the
59+
/// `"unstable-darwin-objc"` feature which uses the nightly-only `darwin_objc`
60+
/// language feature. This experimental language feature implements the
61+
/// Objective-C static selector ABI directly in the Rust compiler and should
62+
/// work in more if not all cases. Using `"unstable-darwin-objc"` requires
63+
/// `darwin_objc` to be enabled in every crate that uses this macro, which can
64+
/// be achieved in `objc2` crates by enabling their own
65+
/// `"unstable-darwin-objc"` features and in your own crates by adding
66+
/// `#![feature(darwin_objc)]`.
67+
///
68+
/// See [rust-lang/rust#145496] for the tracking issue for the feature.
69+
///
70+
/// `"unstable-static-sel"` and `"unstable-static-sel-inlined"` take
71+
/// precedence over `"unstable-darwin-objc"`.
72+
///
5873
/// [rust-lang/rust#53929]: https://github.com/rust-lang/rust/issues/53929
74+
/// [rust-lang/rust#145496]: https://github.com/rust-lang/rust/issues/145496
5975
///
6076
///
6177
/// # Examples
@@ -177,9 +193,9 @@ macro_rules! __sel_helper {
177193
// Base-case
178194
{
179195
($($parsed_sel:tt)*)
180-
} => ({
196+
} => {
181197
$crate::__sel_data!($($parsed_sel)*)
182-
});
198+
};
183199
// Single identifier
184200
{
185201
()
@@ -219,20 +235,36 @@ macro_rules! __sel_data {
219235
$crate::__macros::concat!(
220236
$crate::__macros::stringify!($first),
221237
$(':', $($($crate::__macros::stringify!($rest),)? ':',)*)?
222-
'\0',
223238
)
224239
};
225240
}
226241

227242
#[doc(hidden)]
228243
#[macro_export]
229-
#[cfg(not(feature = "unstable-static-sel"))]
244+
#[cfg(not(any(feature = "unstable-darwin-objc", feature = "unstable-static-sel")))]
230245
macro_rules! __sel_inner {
231246
($data:expr, $_hash:expr) => {{
232247
static CACHED_SEL: $crate::__macros::CachedSel = $crate::__macros::CachedSel::new();
233248
#[allow(unused_unsafe)]
234249
unsafe {
235-
CACHED_SEL.get($data)
250+
CACHED_SEL.get($crate::__macros::concat!($data, '\0'))
251+
}
252+
}};
253+
}
254+
255+
#[doc(hidden)]
256+
#[macro_export]
257+
#[cfg(all(
258+
feature = "unstable-darwin-objc",
259+
not(feature = "unstable-static-sel")
260+
))]
261+
macro_rules! __sel_inner {
262+
($data:expr, $_hash:expr) => {{
263+
let ptr = $crate::__macros::core_darwin_objc::selector!($data);
264+
let ptr = ptr.cast_const().cast::<$crate::__macros::u8>();
265+
#[allow(unused_unsafe)]
266+
unsafe {
267+
$crate::runtime::Sel::__internal_from_ptr(ptr)
236268
}
237269
}};
238270
}
@@ -245,7 +277,7 @@ macro_rules! __statics_sel {
245277
($data:expr)
246278
($hash:expr)
247279
} => {
248-
const X: &[$crate::__macros::u8] = $data.as_bytes();
280+
const X: &[$crate::__macros::u8] = $crate::__macros::concat!($data, '\0').as_bytes();
249281

250282
/// Clang marks this with LLVM's `unnamed_addr`.
251283
/// See rust-lang/rust#18297
@@ -425,30 +457,30 @@ impl CachedSel {
425457

426458
#[inline]
427459
pub fn alloc_sel() -> Sel {
428-
__sel_inner!("alloc\0", "alloc")
460+
__sel_inner!("alloc", "alloc")
429461
}
430462

431463
#[inline]
432464
pub fn init_sel() -> Sel {
433-
__sel_inner!("init\0", "init")
465+
__sel_inner!("init", "init")
434466
}
435467

436468
#[inline]
437469
pub fn new_sel() -> Sel {
438-
__sel_inner!("new\0", "new")
470+
__sel_inner!("new", "new")
439471
}
440472

441473
#[inline]
442474
pub fn dealloc_sel() -> Sel {
443-
__sel_inner!("dealloc\0", "dealloc")
475+
__sel_inner!("dealloc", "dealloc")
444476
}
445477

446478
/// An undocumented selector called by the Objective-C runtime when
447479
/// initializing instance variables.
448480
#[inline]
449481
#[allow(dead_code)] // May be useful in the future
450482
fn cxx_construct_sel() -> Sel {
451-
__sel_inner!(".cxx_construct\0", ".cxx_construct")
483+
__sel_inner!(".cxx_construct", ".cxx_construct")
452484
}
453485

454486
/// Objective-C runtimes call `.cxx_destruct` as part of the final `dealloc`
@@ -485,7 +517,7 @@ fn cxx_construct_sel() -> Sel {
485517
#[inline]
486518
#[allow(dead_code)] // May be useful in the future
487519
fn cxx_destruct_sel() -> Sel {
488-
__sel_inner!(".cxx_destruct\0", ".cxx_destruct")
520+
__sel_inner!(".cxx_destruct", ".cxx_destruct")
489521
}
490522

491523
#[cfg(test)]

crates/objc2/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
//! [#203]: https://github.com/madsmtm/objc2/issues/203
103103
104104
#![no_std]
105+
#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]
105106
#![cfg_attr(
106107
feature = "unstable-autoreleasesafe",
107108
feature(negative_impls, auto_traits)

examples/app/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ path = "default_xcode_app/main.rs"
1818
name = "hello_world_app"
1919
path = "hello_world_app.rs"
2020

21+
[features]
22+
unstable-darwin-objc = []
23+
2124
[dependencies]
2225
objc2 = "0.6.2"
2326
objc2-foundation = { version = "0.3.1", default-features = false, features = [

examples/app/default_xcode_app/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
//! Using a Storyboard outside of Xcode is quite involved, so instead, we set
44
//! up the entire UI (menubar and window) ourselves.
55
6+
#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]
7+
68
use objc2::MainThreadMarker;
79
use objc2_app_kit::NSApplication;
810

examples/app/delegate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Implementing `NSApplicationDelegate` for a custom class.
22
#![deny(unsafe_op_in_unsafe_fn)]
3+
#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]
34
use objc2::rc::Retained;
45
use objc2::runtime::ProtocolObject;
56
use objc2::{define_class, msg_send, DefinedClass, MainThreadMarker, MainThreadOnly};

examples/app/hello_world_app.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![deny(unsafe_op_in_unsafe_fn)]
2+
#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]
23
use std::cell::OnceCell;
34

45
use objc2::rc::Retained;

0 commit comments

Comments
 (0)