Skip to content

Commit 9bd26ee

Browse files
authored
Merge pull request #761 from jbatez/core_ffi_objc
Add `unstable-darwin-objc` feature
2 parents cefedf4 + f9490f8 commit 9bd26ee

File tree

391 files changed

+516
-15
lines changed

Some content is hidden

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

391 files changed

+516
-15
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ disable-encoding-assertions = []
7272
# no longer required.
7373
verify = []
7474

75-
# Make the `sel!` macro look up the selector statically.
75+
# Make the `sel!`/`class!` macro look up the item statically.
7676
#
7777
# The plan is to enable this by default, but right now we are uncertain of
7878
# its stability, and it might need significant changes before being fully
@@ -85,6 +85,9 @@ unstable-static-sel-inlined = ["unstable-static-sel"]
8585
unstable-static-class = ["dep:objc2-proc-macros"]
8686
unstable-static-class-inlined = ["unstable-static-class"]
8787

88+
# Augment the above with the nightly `darwin_objc` feature.
89+
unstable-darwin-objc = []
90+
8891
# Uses nightly features to make autorelease pools fully sound
8992
unstable-autoreleasesafe = []
9093

crates/objc2/src/__macros/class.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,23 @@ macro_rules! __class_inner {
8989
}};
9090
}
9191

92+
#[doc(hidden)]
93+
#[macro_export]
94+
#[cfg(all(
95+
feature = "unstable-static-class",
96+
feature = "unstable-darwin-objc",
97+
not(feature = "gnustep-1-7"),
98+
))]
99+
macro_rules! __class_inner {
100+
($name:expr, $_hash:expr) => {{
101+
let ptr = $crate::__macros::core_darwin_objc::class!($name);
102+
let ptr = ptr.cast_const().cast::<$crate::runtime::AnyClass>();
103+
#[allow(unused_unsafe)]
104+
let r: &'static $crate::runtime::AnyClass = unsafe { &*ptr };
105+
r
106+
}};
107+
}
108+
92109
#[doc(hidden)]
93110
#[macro_export]
94111
#[cfg(all(
@@ -175,6 +192,7 @@ macro_rules! __statics_class {
175192
#[macro_export]
176193
#[cfg(all(
177194
feature = "unstable-static-class",
195+
not(feature = "unstable-darwin-objc"),
178196
not(feature = "gnustep-1-7"),
179197
not(feature = "unstable-static-class-inlined")
180198
))]
@@ -199,6 +217,7 @@ macro_rules! __class_inner {
199217
#[macro_export]
200218
#[cfg(all(
201219
feature = "unstable-static-class",
220+
not(feature = "unstable-darwin-objc"),
202221
not(feature = "gnustep-1-7"),
203222
feature = "unstable-static-class-inlined"
204223
))]

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 & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,26 @@ 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+
///
5870
/// [rust-lang/rust#53929]: https://github.com/rust-lang/rust/issues/53929
71+
/// [rust-lang/rust#145496]: https://github.com/rust-lang/rust/issues/145496
5972
///
6073
///
6174
/// # Examples
@@ -177,9 +190,9 @@ macro_rules! __sel_helper {
177190
// Base-case
178191
{
179192
($($parsed_sel:tt)*)
180-
} => ({
193+
} => {
181194
$crate::__sel_data!($($parsed_sel)*)
182-
});
195+
};
183196
// Single identifier
184197
{
185198
()
@@ -219,7 +232,6 @@ macro_rules! __sel_data {
219232
$crate::__macros::concat!(
220233
$crate::__macros::stringify!($first),
221234
$(':', $($($crate::__macros::stringify!($rest),)? ':',)*)?
222-
'\0',
223235
)
224236
};
225237
}
@@ -232,7 +244,21 @@ macro_rules! __sel_inner {
232244
static CACHED_SEL: $crate::__macros::CachedSel = $crate::__macros::CachedSel::new();
233245
#[allow(unused_unsafe)]
234246
unsafe {
235-
CACHED_SEL.get($data)
247+
CACHED_SEL.get($crate::__macros::concat!($data, '\0'))
248+
}
249+
}};
250+
}
251+
252+
#[doc(hidden)]
253+
#[macro_export]
254+
#[cfg(all(feature = "unstable-static-sel", feature = "unstable-darwin-objc"))]
255+
macro_rules! __sel_inner {
256+
($data:expr, $_hash:expr) => {{
257+
let ptr = $crate::__macros::core_darwin_objc::selector!($data);
258+
let ptr = ptr.cast_const().cast::<$crate::__macros::u8>();
259+
#[allow(unused_unsafe)]
260+
unsafe {
261+
$crate::runtime::Sel::__internal_from_ptr(ptr)
236262
}
237263
}};
238264
}
@@ -245,7 +271,7 @@ macro_rules! __statics_sel {
245271
($data:expr)
246272
($hash:expr)
247273
} => {
248-
const X: &[$crate::__macros::u8] = $data.as_bytes();
274+
const X: &[$crate::__macros::u8] = $crate::__macros::concat!($data, '\0').as_bytes();
249275

250276
/// Clang marks this with LLVM's `unnamed_addr`.
251277
/// See rust-lang/rust#18297
@@ -321,7 +347,8 @@ macro_rules! __statics_sel {
321347
#[macro_export]
322348
#[cfg(all(
323349
feature = "unstable-static-sel",
324-
not(feature = "unstable-static-sel-inlined")
350+
not(feature = "unstable-darwin-objc"),
351+
not(feature = "unstable-static-sel-inlined"),
325352
))]
326353
macro_rules! __sel_inner {
327354
($data:expr, $hash:expr) => {{
@@ -353,7 +380,11 @@ macro_rules! __sel_inner {
353380

354381
#[doc(hidden)]
355382
#[macro_export]
356-
#[cfg(feature = "unstable-static-sel-inlined")]
383+
#[cfg(all(
384+
feature = "unstable-static-sel",
385+
not(feature = "unstable-darwin-objc"),
386+
feature = "unstable-static-sel-inlined",
387+
))]
357388
macro_rules! __sel_inner {
358389
($data:expr, $hash:expr) => {{
359390
$crate::__statics_sel! {
@@ -425,30 +456,30 @@ impl CachedSel {
425456

426457
#[inline]
427458
pub fn alloc_sel() -> Sel {
428-
__sel_inner!("alloc\0", "alloc")
459+
__sel_inner!("alloc", "alloc")
429460
}
430461

431462
#[inline]
432463
pub fn init_sel() -> Sel {
433-
__sel_inner!("init\0", "init")
464+
__sel_inner!("init", "init")
434465
}
435466

436467
#[inline]
437468
pub fn new_sel() -> Sel {
438-
__sel_inner!("new\0", "new")
469+
__sel_inner!("new", "new")
439470
}
440471

441472
#[inline]
442473
pub fn dealloc_sel() -> Sel {
443-
__sel_inner!("dealloc\0", "dealloc")
474+
__sel_inner!("dealloc", "dealloc")
444475
}
445476

446477
/// An undocumented selector called by the Objective-C runtime when
447478
/// initializing instance variables.
448479
#[inline]
449480
#[allow(dead_code)] // May be useful in the future
450481
fn cxx_construct_sel() -> Sel {
451-
__sel_inner!(".cxx_construct\0", ".cxx_construct")
482+
__sel_inner!(".cxx_construct", ".cxx_construct")
452483
}
453484

454485
/// Objective-C runtimes call `.cxx_destruct` as part of the final `dealloc`
@@ -485,7 +516,7 @@ fn cxx_construct_sel() -> Sel {
485516
#[inline]
486517
#[allow(dead_code)] // May be useful in the future
487518
fn cxx_destruct_sel() -> Sel {
488-
__sel_inner!(".cxx_destruct\0", ".cxx_destruct")
519+
__sel_inner!(".cxx_destruct", ".cxx_destruct")
489520
}
490521

491522
#[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: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ 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+
"objc2/unstable-darwin-objc",
24+
"objc2-app-kit/unstable-darwin-objc",
25+
"objc2-foundation/unstable-darwin-objc",
26+
]
27+
2128
[dependencies]
2229
objc2 = "0.6.2"
2330
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};

0 commit comments

Comments
 (0)