Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions crates/header-translator/src/library.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@ impl Library {
)?;
writeln!(lib_rs, "//! [framework-crates]: https://docs.rs/objc2/latest/objc2/topics/about_generated/index.html")?;
writeln!(lib_rs, "#![no_std]")?;
if !self.data.is_library {
writeln!(
lib_rs,
"#![cfg_attr(feature = \"unstable-darwin-objc\", feature(darwin_objc))]"
)?;
}
writeln!(lib_rs, "#![cfg_attr(docsrs, feature(doc_auto_cfg))]")?;
writeln!(lib_rs, "// Update in Cargo.toml as well.")?;
writeln!(
Expand Down Expand Up @@ -447,6 +453,20 @@ see that for related crates.", self.data.krate)?;
cargo_toml["features"][feature] = array_with_newlines(enabled_features);
}

// Emit unstable-darwin-objc feature in framework crates.
//
// We could also use this to enable the feature automatically in
// dependencies, but we'd like for this feature to remain "unstable" in
// the sense that we'd be free to remove it in a patch release. By
// mentioning it across crates, that would no longer be the case.
//
// It's slightly less convenient for users, but in practice, most users
// already directly depend on all their `objc2-*` crates in their
// dependency tree.
if !self.data.is_library {
cargo_toml["features"]["unstable-darwin-objc"] = array_with_newlines([]);
}

// And then the rest of the features.
if !emitted_features.is_empty() {
add_newline_at_end(&mut cargo_toml["features"]);
Expand Down
5 changes: 4 additions & 1 deletion crates/objc2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ disable-encoding-assertions = []
# no longer required.
verify = []

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

# Augment the above with the nightly `darwin_objc` feature.
unstable-darwin-objc = []

# Uses nightly features to make autorelease pools fully sound
unstable-autoreleasesafe = []

Expand Down
19 changes: 19 additions & 0 deletions crates/objc2/src/__macros/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,23 @@ macro_rules! __class_inner {
}};
}

#[doc(hidden)]
#[macro_export]
#[cfg(all(
feature = "unstable-static-class",
feature = "unstable-darwin-objc",
not(feature = "gnustep-1-7"),
))]
macro_rules! __class_inner {
($name:expr, $_hash:expr) => {{
let ptr = $crate::__macros::core_darwin_objc::class!($name);
let ptr = ptr.cast_const().cast::<$crate::runtime::AnyClass>();
#[allow(unused_unsafe)]
let r: &'static $crate::runtime::AnyClass = unsafe { &*ptr };
r
}};
}

#[doc(hidden)]
#[macro_export]
#[cfg(all(
Expand Down Expand Up @@ -175,6 +192,7 @@ macro_rules! __statics_class {
#[macro_export]
#[cfg(all(
feature = "unstable-static-class",
not(feature = "unstable-darwin-objc"),
not(feature = "gnustep-1-7"),
not(feature = "unstable-static-class-inlined")
))]
Expand All @@ -199,6 +217,7 @@ macro_rules! __class_inner {
#[macro_export]
#[cfg(all(
feature = "unstable-static-class",
not(feature = "unstable-darwin-objc"),
not(feature = "gnustep-1-7"),
feature = "unstable-static-class-inlined"
))]
Expand Down
3 changes: 3 additions & 0 deletions crates/objc2/src/__macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ pub use core::primitive::{bool, isize, str, u8};
pub use core::{compile_error, concat, env, module_path, panic, stringify};
pub use std::sync::Once;

#[cfg(feature = "unstable-darwin-objc")]
pub use core::os::darwin::objc as core_darwin_objc;

pub use self::available::{is_available, AvailableVersion, OSVersion};
pub use self::class::{disallow_in_static, CachedClass};
pub use self::convert::{ConvertArgument, ConvertArguments, ConvertReturn, TupleExtender};
Expand Down
59 changes: 45 additions & 14 deletions crates/objc2/src/__macros/sel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,26 @@ use crate::runtime::Sel;
/// - runtime, causing UB (unlikely)
///
/// The `"unstable-static-sel-inlined"` feature is the even more extreme
/// version - it yields the best performance and is closest to real
/// version - it yield better performance and is closer to real
/// Objective-C code, but probably won't work unless your code and its
/// inlining is written in a very certain way.
///
/// Enabling LTO greatly increases the chance that these features work.
///
/// On Apple/Darwin targets, these limitations can be overcome with the
/// `"unstable-darwin-objc"` feature which uses the nightly-only `darwin_objc`
/// language feature. This experimental language feature implements the
/// Objective-C static selector ABI directly in the Rust compiler and should
/// work in more if not all cases. Using `"unstable-darwin-objc"` requires
/// `darwin_objc` to be enabled in every crate that uses this macro, which can
/// be achieved in `objc2` crates by enabling their own
/// `"unstable-darwin-objc"` features and in your own crates by adding
/// `#![feature(darwin_objc)]`.
///
/// See [rust-lang/rust#145496] for the tracking issue for the feature.
///
/// [rust-lang/rust#53929]: https://github.com/rust-lang/rust/issues/53929
/// [rust-lang/rust#145496]: https://github.com/rust-lang/rust/issues/145496
///
///
/// # Examples
Expand Down Expand Up @@ -177,9 +190,9 @@ macro_rules! __sel_helper {
// Base-case
{
($($parsed_sel:tt)*)
} => ({
} => {
$crate::__sel_data!($($parsed_sel)*)
});
};
// Single identifier
{
()
Expand Down Expand Up @@ -219,7 +232,6 @@ macro_rules! __sel_data {
$crate::__macros::concat!(
$crate::__macros::stringify!($first),
$(':', $($($crate::__macros::stringify!($rest),)? ':',)*)?
'\0',
)
};
}
Expand All @@ -232,7 +244,21 @@ macro_rules! __sel_inner {
static CACHED_SEL: $crate::__macros::CachedSel = $crate::__macros::CachedSel::new();
#[allow(unused_unsafe)]
unsafe {
CACHED_SEL.get($data)
CACHED_SEL.get($crate::__macros::concat!($data, '\0'))
}
}};
}

#[doc(hidden)]
#[macro_export]
#[cfg(all(feature = "unstable-static-sel", feature = "unstable-darwin-objc"))]
macro_rules! __sel_inner {
($data:expr, $_hash:expr) => {{
let ptr = $crate::__macros::core_darwin_objc::selector!($data);
let ptr = ptr.cast_const().cast::<$crate::__macros::u8>();
#[allow(unused_unsafe)]
unsafe {
$crate::runtime::Sel::__internal_from_ptr(ptr)
}
}};
}
Expand All @@ -245,7 +271,7 @@ macro_rules! __statics_sel {
($data:expr)
($hash:expr)
} => {
const X: &[$crate::__macros::u8] = $data.as_bytes();
const X: &[$crate::__macros::u8] = $crate::__macros::concat!($data, '\0').as_bytes();

/// Clang marks this with LLVM's `unnamed_addr`.
/// See rust-lang/rust#18297
Expand Down Expand Up @@ -321,7 +347,8 @@ macro_rules! __statics_sel {
#[macro_export]
#[cfg(all(
feature = "unstable-static-sel",
not(feature = "unstable-static-sel-inlined")
not(feature = "unstable-darwin-objc"),
not(feature = "unstable-static-sel-inlined"),
))]
macro_rules! __sel_inner {
($data:expr, $hash:expr) => {{
Expand Down Expand Up @@ -353,7 +380,11 @@ macro_rules! __sel_inner {

#[doc(hidden)]
#[macro_export]
#[cfg(feature = "unstable-static-sel-inlined")]
#[cfg(all(
feature = "unstable-static-sel",
not(feature = "unstable-darwin-objc"),
feature = "unstable-static-sel-inlined",
))]
macro_rules! __sel_inner {
($data:expr, $hash:expr) => {{
$crate::__statics_sel! {
Expand Down Expand Up @@ -425,30 +456,30 @@ impl CachedSel {

#[inline]
pub fn alloc_sel() -> Sel {
__sel_inner!("alloc\0", "alloc")
__sel_inner!("alloc", "alloc")
}

#[inline]
pub fn init_sel() -> Sel {
__sel_inner!("init\0", "init")
__sel_inner!("init", "init")
}

#[inline]
pub fn new_sel() -> Sel {
__sel_inner!("new\0", "new")
__sel_inner!("new", "new")
}

#[inline]
pub fn dealloc_sel() -> Sel {
__sel_inner!("dealloc\0", "dealloc")
__sel_inner!("dealloc", "dealloc")
}

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

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

#[cfg(test)]
Expand Down
1 change: 1 addition & 0 deletions crates/objc2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
//! [#203]: https://github.com/madsmtm/objc2/issues/203

#![no_std]
#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]
#![cfg_attr(
feature = "unstable-autoreleasesafe",
feature(negative_impls, auto_traits)
Expand Down
7 changes: 7 additions & 0 deletions examples/app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ path = "default_xcode_app/main.rs"
name = "hello_world_app"
path = "hello_world_app.rs"

[features]
unstable-darwin-objc = [
"objc2/unstable-darwin-objc",
"objc2-app-kit/unstable-darwin-objc",
"objc2-foundation/unstable-darwin-objc",
]

[dependencies]
objc2 = "0.6.2"
objc2-foundation = { version = "0.3.1", default-features = false, features = [
Expand Down
2 changes: 2 additions & 0 deletions examples/app/default_xcode_app/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
//! Using a Storyboard outside of Xcode is quite involved, so instead, we set
//! up the entire UI (menubar and window) ourselves.

#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]

use objc2::MainThreadMarker;
use objc2_app_kit::NSApplication;

Expand Down
1 change: 1 addition & 0 deletions examples/app/delegate.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Implementing `NSApplicationDelegate` for a custom class.
#![deny(unsafe_op_in_unsafe_fn)]
#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]
use objc2::rc::Retained;
use objc2::runtime::ProtocolObject;
use objc2::{define_class, msg_send, DefinedClass, MainThreadMarker, MainThreadOnly};
Expand Down
1 change: 1 addition & 0 deletions examples/app/hello_world_app.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![deny(unsafe_op_in_unsafe_fn)]
#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]
use std::cell::OnceCell;

use objc2::rc::Retained;
Expand Down
6 changes: 6 additions & 0 deletions examples/audio/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ publish = false
name = "speech_synthesis"
path = "speech_synthesis.rs"

[features]
unstable-darwin-objc = [
"objc2/unstable-darwin-objc",
"objc2-foundation/unstable-darwin-objc",
]

[dependencies]
objc2 = "0.6.2"
objc2-foundation = { version = "0.3.1", default-features = false, features = [
Expand Down
1 change: 1 addition & 0 deletions examples/audio/speech_synthesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//! Works on macOS >= 10.7 and iOS > 7.0.
#![deny(unsafe_op_in_unsafe_fn)]
#![allow(unused_imports)]
#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]

use std::thread;
use std::time::Duration;
Expand Down
13 changes: 13 additions & 0 deletions examples/metal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ path = "triangle/main.rs"
name = "default_xcode_game"
path = "default_xcode_game/main.rs"

[features]
unstable-darwin-objc = [
"objc2/unstable-darwin-objc",
"objc2-app-kit/unstable-darwin-objc",
"objc2-core-foundation/unstable-darwin-objc",
"objc2-foundation/unstable-darwin-objc",
"objc2-metal-kit/unstable-darwin-objc",
"objc2-metal/unstable-darwin-objc",
"objc2-model-io/unstable-darwin-objc",
"objc2-quartz-core/unstable-darwin-objc",
]

[dependencies]
objc2 = "0.6.2"
dispatch2 = "0.3.0"
Expand Down Expand Up @@ -62,6 +74,7 @@ objc2-core-foundation = { version = "0.3.1", default-features = false, features
"std",
"CFCGTypes",
] }
objc2-quartz-core = { version = "0.3.1", default-features = false, features = [] }

[target.'cfg(target_os = "macos")'.dependencies]
objc2-app-kit = { version = "0.3.1", default-features = false, features = [
Expand Down
2 changes: 2 additions & 0 deletions examples/metal/default_xcode_game/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
//! NOTE: Using a Storyboard outside of Xcode is quite involved, so instead,
//! we set up the entire UI (menubar and window) ourselves.

#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]

#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
use objc2::MainThreadMarker;
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
Expand Down
1 change: 1 addition & 0 deletions examples/metal/triangle/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![deny(unsafe_op_in_unsafe_fn)]
#![allow(clippy::incompatible_msrv)]
#![cfg_attr(not(target_os = "macos"), allow(dead_code, unused))]
#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]

use core::{cell::OnceCell, ptr::NonNull};

Expand Down
8 changes: 8 additions & 0 deletions examples/testing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ path = "screenshot.rs"
name = "ui_test"
path = "ui_test.rs"

[features]
unstable-darwin-objc = [
"objc2/unstable-darwin-objc",
"objc2-foundation/unstable-darwin-objc",
"objc2-xc-test/unstable-darwin-objc",
"objc2-xc-ui-automation/unstable-darwin-objc",
]

[dependencies]
objc2 = "0.6.2"
objc2-foundation = { version = "0.3.1", default-features = false, features = [
Expand Down
1 change: 1 addition & 0 deletions examples/testing/screenshot.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![no_main] // Required, we build this with `-bundle`.
#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]

use objc2::{define_class, ClassType, MainThreadOnly};
use objc2_foundation::ns_string;
Expand Down
1 change: 1 addition & 0 deletions examples/testing/ui_test.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![no_main] // Required, we build this with `-bundle`.
#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]

use objc2::{define_class, ClassType, MainThreadOnly};
use objc2_xc_test::XCTestCase;
Expand Down
Loading