From bbf81aca542d6ae50fc1474fccd8783be993ae61 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 2 Jun 2024 17:21:20 +0200 Subject: [PATCH] Allow using C-unwind in stable Rust Improves the situation in https://github.com/madsmtm/objc2/issues/539. --- .github/workflows/ci.yml | 2 +- crates/objc-sys/Cargo.toml | 8 +++++++- crates/objc-sys/src/lib.rs | 7 +------ crates/objc2/Cargo.toml | 6 ++++-- .../objc2/src/__macro_helpers/common_selectors.rs | 4 +--- crates/objc2/src/exception.rs | 15 ++++++--------- crates/objc2/src/lib.rs | 1 - crates/objc2/src/macros/mod.rs | 6 ++---- 8 files changed, 22 insertions(+), 27 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 02f9f2c50..fe9e9d503 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 diff --git a/crates/objc-sys/Cargo.toml b/crates/objc-sys/Cargo.toml index 6c276c8e4..ebf107277 100644 --- a/crates/objc-sys/Cargo.toml +++ b/crates/objc-sys/Cargo.toml @@ -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 @@ -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", diff --git a/crates/objc-sys/src/lib.rs b/crates/objc-sys/src/lib.rs index 0bb8c6bd2..83ee74847 100644 --- a/crates/objc-sys/src/lib.rs +++ b/crates/objc-sys/src/lib.rs @@ -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. @@ -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); } diff --git a/crates/objc2/Cargo.toml b/crates/objc2/Cargo.toml index 60c247dd9..6ee6da771 100644 --- a/crates/objc2/Cargo.toml +++ b/crates/objc2/Cargo.toml @@ -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 = [] @@ -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", diff --git a/crates/objc2/src/__macro_helpers/common_selectors.rs b/crates/objc2/src/__macro_helpers/common_selectors.rs index 5ee2b4c3f..0274eff14 100644 --- a/crates/objc2/src/__macro_helpers/common_selectors.rs +++ b/crates/objc2/src/__macro_helpers/common_selectors.rs @@ -56,7 +56,7 @@ fn cxx_construct_sel() -> Sel { /// take a selector, unlike every other Objective-C method, see: /// /// -/// 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 @@ -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 diff --git a/crates/objc2/src/exception.rs b/crates/objc2/src/exception.rs index 27eab5d76..9915cc3dc 100644 --- a/crates/objc2/src/exception.rs +++ b/crates/objc2/src/exception.rs @@ -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) -> ! { @@ -274,11 +273,9 @@ unsafe fn try_no_ret(closure: F) -> Result<(), Option( closure: impl FnOnce() -> R + UnwindSafe, diff --git a/crates/objc2/src/lib.rs b/crates/objc2/src/lib.rs index c87209c03..7e5528713 100644 --- a/crates/objc2/src/lib.rs +++ b/crates/objc2/src/lib.rs @@ -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)] diff --git a/crates/objc2/src/macros/mod.rs b/crates/objc2/src/macros/mod.rs index 815f1025e..8c4b4c717 100644 --- a/crates/objc2/src/macros/mod.rs +++ b/crates/objc2/src/macros/mod.rs @@ -831,8 +831,8 @@ 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. @@ -840,8 +840,6 @@ macro_rules! __class_inner { /// 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 ///