Skip to content

Commit

Permalink
Allow using C-unwind in stable Rust
Browse files Browse the repository at this point in the history
Improves the situation in #539.
  • Loading branch information
madsmtm committed Jun 2, 2024
1 parent 60a655d commit bbf81ac
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 27 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ jobs:
key: cargo-${{ github.job }}-${{ matrix.name }}-${{ hashFiles('**/Cargo.lock') }}

- name: cargo check
run: cargo check $PUBLIC_CRATES $FRAMEWORKS_MACOS_14 $INTERESTING_FEATURES
run: cargo check $PUBLIC_CRATES $FRAMEWORKS_MACOS_14 --features=all
env:
RUSTFLAGS: "--codegen=debuginfo=0" # Removed --deny=warnings

Expand Down
8 changes: 7 additions & 1 deletion crates/objc-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ unstable-winobjc = ["gnustep-1-8"]
# Link to ObjFW
unstable-objfw = []

# Use nightly c_unwind feature
# Uses `extern "C-unwind"` on relevant function declarations.
#
# This raises MSRV to `1.71`.
#
# Warning: Enabling this is a breaking change for consumer crates, as it
# changes the signature of functions.
unstable-c-unwind = []

# Private
Expand All @@ -65,6 +70,7 @@ cc = { version = "1.0.80", optional = true }

[package.metadata.docs.rs]
default-target = "aarch64-apple-darwin"
features = ["unstable-c-unwind"]
targets = [
"aarch64-apple-darwin",
"x86_64-apple-darwin",
Expand Down
7 changes: 1 addition & 6 deletions crates/objc-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,8 @@
#![allow(non_snake_case)]
#![allow(missing_debug_implementations)]
#![doc(html_root_url = "https://docs.rs/objc-sys/0.3.5")]
#![cfg_attr(feature = "unstable-c-unwind", feature(c_unwind))]
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg_hide))]
#![cfg_attr(docsrs, doc(cfg_hide(doc)))]
#![cfg_attr(docsrs, doc(cfg_hide(doc, feature = "unstable-c-unwind")))]

// TODO: Remove this and add "no-std" category to Cargo.toml
// Requires a better solution for C-types in `no_std` crates.
Expand Down Expand Up @@ -213,10 +212,6 @@ macro_rules! generate_linking_tests {
// Get function pointer to make the linker require the
// symbol to be available.
let f: unsafe extern $abi fn($($(#[$a_m])* $t),*) $(-> $r)? = crate::$name;
// Workaround for https://github.com/rust-lang/rust/pull/92964
#[cfg(feature = "unstable-c-unwind")]
#[allow(clippy::useless_transmute)]
let f: unsafe extern "C" fn() = unsafe { core::mem::transmute(f) };
// Execute side-effect to ensure it is not optimized away.
std::println!("{:p}", f);
}
Expand Down
6 changes: 4 additions & 2 deletions crates/objc2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ unstable-static-class-inlined = ["unstable-static-class"]
# Uses nightly features to make autorelease pools fully sound
unstable-autoreleasesafe = []

# Uses the nightly c_unwind feature to make throwing safe
# Uses `extern "C-unwind"` to make method calls that throw safe.
#
# This raises MSRV to `1.71`.
#
# You must manually enable `objc-sys/unstable-c-unwind` to use this.
unstable-c-unwind = []
Expand Down Expand Up @@ -137,7 +139,7 @@ harness = false

[package.metadata.docs.rs]
default-target = "aarch64-apple-darwin"
features = ["exception"]
features = ["unstable-c-unwind", "exception"]
targets = [
"aarch64-apple-darwin",
"x86_64-apple-darwin",
Expand Down
4 changes: 1 addition & 3 deletions crates/objc2/src/__macro_helpers/common_selectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn cxx_construct_sel() -> Sel {
/// take a selector, unlike every other Objective-C method, see:
/// <https://github.com/apple-oss-distributions/objc4/blob/objc4-906/runtime/objc-class.mm#L457>
///
/// So the signature is `extern "C" fn(*mut AnyObject)`.
/// So the signature is `extern "C-unwind" fn(*mut AnyObject)`.
///
/// This is likely because it's not a real Objective-C method that can be
/// called from userspace / objc_msgSend, and it's more efficient to not pass
Expand All @@ -67,8 +67,6 @@ fn cxx_construct_sel() -> Sel {
/// convention, where such an ignored parameter would be allowed on all
/// relevant architectures.
///
/// TODO: Unsure whether "C-unwind" is allowed?
///
/// [gcc-docs]: https://gcc.gnu.org/onlinedocs/gcc/Objective-C-and-Objective-C_002b_002b-Dialect-Options.html#index-fobjc-call-cxx-cdtors
#[inline]
#[allow(dead_code)] // May be useful in the future
Expand Down
15 changes: 6 additions & 9 deletions crates/objc2/src/exception.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,11 @@ impl RefUnwindSafe for Exception {}
/// Objective-C exception handler like [`catch`] (and specifically not
/// [`catch_unwind`]).
///
/// This also invokes undefined behaviour until `C-unwind` is stabilized, see
/// [RFC-2945] - you can try this out on nightly using the `unstable-c-unwind`
/// feature flag.
/// This also invokes undefined behaviour unless `C-unwind` is used, which it
/// only is if the `unstable-c-unwind` feature flag is enabled (raises MSRV to
/// 1.71).
///
/// [`catch_unwind`]: std::panic::catch_unwind
/// [RFC-2945]: https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html
#[inline]
#[cfg(feature = "exception")] // For consistency, not strictly required
pub unsafe fn throw(exception: Retained<Exception>) -> ! {
Expand Down Expand Up @@ -274,11 +273,9 @@ unsafe fn try_no_ret<F: FnOnce()>(closure: F) -> Result<(), Option<Retained<Exce
/// The given closure must not panic (e.g. normal Rust unwinding into this
/// causes undefined behaviour).
///
/// Additionally, this unwinds through the closure from Objective-C, which is
/// undefined behaviour until `C-unwind` is stabilized, see [RFC-2945] - you
/// can try this out on nightly using the `unstable-c-unwind` feature flag.
///
/// [RFC-2945]: https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html
/// This also invokes undefined behaviour unless `C-unwind` is used, which it
/// only is if the `unstable-c-unwind` feature flag is enabled (raises MSRV to
/// 1.71).
#[cfg(feature = "exception")]
pub unsafe fn catch<R>(
closure: impl FnOnce() -> R + UnwindSafe,
Expand Down
1 change: 0 additions & 1 deletion crates/objc2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@
feature = "unstable-autoreleasesafe",
feature(negative_impls, auto_traits)
)]
#![cfg_attr(feature = "unstable-c-unwind", feature(c_unwind))]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
#![warn(missing_docs)]
#![warn(clippy::missing_errors_doc)]
Expand Down
6 changes: 2 additions & 4 deletions crates/objc2/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -831,17 +831,15 @@ macro_rules! __class_inner {
/// # Panics
///
/// Panics if the `"catch-all"` feature is enabled and the Objective-C method
/// throws an exception. Exceptions may still cause UB until
/// `extern "C-unwind"` is stable, see [RFC-2945].
/// throws an exception. Exceptions may still cause UB unless you enable the
/// `"unstable-c-unwind"` feature (raises MSRV to 1.71).
///
/// Panics if `debug_assertions` are enabled and the Objective-C method's
/// encoding does not match the encoding of the given arguments and return.
///
/// And panics if the `NSError**` handling functionality described above is
/// used, and the error object was unexpectedly `NULL`.
///
/// [RFC-2945]: https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html
///
///
/// # Safety
///
Expand Down

0 comments on commit bbf81ac

Please sign in to comment.