Skip to content

Commit 3aa3b6a

Browse files
authored
Rollup merge of rust-lang#145660 - jbatez:darwin_objc, r=jdonszelmann,madsmtm,tmandry
initial implementation of the darwin_objc unstable feature Tracking issue: rust-lang#145496 This feature makes it possible to reference Objective-C classes and selectors using the same ABI used by native Objective-C on Apple/Darwin platforms. Without it, Rust code interacting with Objective-C must resort to loading classes and selectors using costly string-based lookups at runtime. With it, these references can be loaded efficiently at dynamic load time. r? ```@tmandry``` try-job: `*apple*` try-job: `x86_64-gnu-nopt`
2 parents 9d72cb0 + b83b100 commit 3aa3b6a

File tree

6 files changed

+172
-0
lines changed

6 files changed

+172
-0
lines changed

core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ pub mod io;
313313
pub mod iter;
314314
pub mod net;
315315
pub mod option;
316+
pub mod os;
316317
pub mod panic;
317318
pub mod panicking;
318319
#[unstable(feature = "pattern_type_macro", issue = "123646")]

core/src/os/darwin/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//! Platform-specific extensions to `core` for Darwin / Apple platforms.
2+
//!
3+
//! This is available on the following operating systems:
4+
//! - macOS
5+
//! - iOS
6+
//! - tvOS
7+
//! - watchOS
8+
//! - visionOS
9+
//!
10+
//! Note: This module is called "Darwin" as that's the name of the underlying
11+
//! core OS of the above operating systems, but it should not be confused with
12+
//! the `-darwin` suffix in the `x86_64-apple-darwin` and
13+
//! `aarch64-apple-darwin` target names, which are mostly named that way for
14+
//! legacy reasons.
15+
16+
#![unstable(feature = "darwin_objc", issue = "145496")]
17+
#![doc(cfg(target_vendor = "apple"))]
18+
19+
pub mod objc;

core/src/os/darwin/objc.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//! Defines types and macros for Objective-C interoperability.
2+
3+
#![unstable(feature = "darwin_objc", issue = "145496")]
4+
#![allow(nonstandard_style)]
5+
6+
use crate::fmt;
7+
8+
/// Equivalent to Objective-C’s `struct objc_class` type.
9+
#[cfg_attr(not(doc), repr(u8))] // An implementation detail we don't want to show up in rustdoc
10+
pub enum objc_class {
11+
#[unstable(
12+
feature = "objc_class_variant",
13+
reason = "temporary implementation detail",
14+
issue = "none"
15+
)]
16+
#[doc(hidden)]
17+
__variant1,
18+
#[unstable(
19+
feature = "objc_class_variant",
20+
reason = "temporary implementation detail",
21+
issue = "none"
22+
)]
23+
#[doc(hidden)]
24+
__variant2,
25+
}
26+
27+
impl fmt::Debug for objc_class {
28+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29+
f.debug_struct("objc_class").finish()
30+
}
31+
}
32+
33+
/// Equivalent to Objective-C’s `struct objc_selector` type.
34+
#[cfg_attr(not(doc), repr(u8))] // An implementation detail we don't want to show up in rustdoc
35+
pub enum objc_selector {
36+
#[unstable(
37+
feature = "objc_selector_variant",
38+
reason = "temporary implementation detail",
39+
issue = "none"
40+
)]
41+
#[doc(hidden)]
42+
__variant1,
43+
#[unstable(
44+
feature = "objc_selector_variant",
45+
reason = "temporary implementation detail",
46+
issue = "none"
47+
)]
48+
#[doc(hidden)]
49+
__variant2,
50+
}
51+
52+
impl fmt::Debug for objc_selector {
53+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54+
f.debug_struct("objc_selector").finish()
55+
}
56+
}
57+
58+
/// Equivalent to Objective-C’s `Class` type.
59+
pub type Class = *mut objc_class;
60+
61+
/// Equivalent to Objective-C’s `SEL` type.
62+
pub type SEL = *mut objc_selector;
63+
64+
/// Gets a reference to an Objective-C class.
65+
///
66+
/// This macro will yield an expression of type [`Class`] for the given class name string literal.
67+
///
68+
/// # Example
69+
///
70+
/// ```no_run
71+
/// #![feature(darwin_objc)]
72+
/// use core::os::darwin::objc;
73+
///
74+
/// let string_class = objc::class!("NSString");
75+
/// ```
76+
#[allow_internal_unstable(rustc_attrs)]
77+
pub macro class($classname:expr) {{
78+
// Since static Objective-C class references actually end up with multiple definitions
79+
// across dylib boundaries, we only expose the value of the static and don't provide a way to
80+
// get the address of or a reference to the static.
81+
unsafe extern "C" {
82+
#[rustc_objc_class = $classname]
83+
safe static VAL: $crate::os::darwin::objc::Class;
84+
}
85+
VAL
86+
}}
87+
88+
/// Gets a reference to an Objective-C selector.
89+
///
90+
/// This macro will yield an expression of type [`SEL`] for the given method name string literal.
91+
///
92+
/// It is similar to Objective-C’s `@selector` directive.
93+
///
94+
/// # Examples
95+
///
96+
/// ```no_run
97+
/// #![feature(darwin_objc)]
98+
/// use core::os::darwin::objc;
99+
///
100+
/// let alloc_sel = objc::selector!("alloc");
101+
/// let init_sel = objc::selector!("initWithCString:encoding:");
102+
/// ```
103+
#[allow_internal_unstable(rustc_attrs)]
104+
pub macro selector($methname:expr) {{
105+
// Since static Objective-C selector references actually end up with multiple definitions
106+
// across dylib boundaries, we only expose the value of the static and don't provide a way to
107+
// get the address of or a reference to the static.
108+
unsafe extern "C" {
109+
#[rustc_objc_selector = $methname]
110+
safe static VAL: $crate::os::darwin::objc::SEL;
111+
}
112+
VAL
113+
}}

core/src/os/mod.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//! OS-specific functionality.
2+
3+
#![unstable(feature = "darwin_objc", issue = "145496")]
4+
5+
#[cfg(all(
6+
doc,
7+
any(
8+
all(target_arch = "wasm32", not(target_os = "wasi")),
9+
all(target_vendor = "fortanix", target_env = "sgx")
10+
)
11+
))]
12+
#[unstable(issue = "none", feature = "std_internals")]
13+
pub mod darwin {}
14+
15+
// darwin
16+
#[cfg(not(all(
17+
doc,
18+
any(
19+
all(target_arch = "wasm32", not(target_os = "wasi")),
20+
all(target_vendor = "fortanix", target_env = "sgx")
21+
)
22+
)))]
23+
#[cfg(any(target_vendor = "apple", doc))]
24+
pub mod darwin;

std/src/os/darwin/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#![doc(cfg(target_vendor = "apple"))]
1818

1919
pub mod fs;
20+
pub mod objc;
21+
2022
// deprecated, but used for public reexport under `std::os::unix::raw`, as
2123
// well as `std::os::macos`/`std::os::ios`, because those modules precede the
2224
// decision to remove these.

std/src/os/darwin/objc.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//! Defines types and macros for Objective-C interoperability.
2+
//!
3+
//! This module re-exports all the items in [`core::os::darwin::objc`].
4+
//!
5+
//! [`core::os::darwin::objc`]: ../../../../core/os/darwin/objc/index.html "mod core::os::darwin::objc"
6+
7+
#![unstable(feature = "darwin_objc", issue = "145496")]
8+
9+
// We can't generate an intra-doc link for this automatically since `core::os::darwin` isn't
10+
// compiled into `core` on every platform even though it's documented on every platform.
11+
// We just link to it directly in the module documentation above instead.
12+
#[cfg(not(doc))]
13+
pub use core::os::darwin::objc::*;

0 commit comments

Comments
 (0)