From fd659b5f35cde9a39c4878069132163d7eb687e5 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 7 Sep 2023 11:38:23 +0200 Subject: [PATCH] Require Send + Sync for object types Without this, it is possible to send types that contain non-threadsafe constructs like `RefCell` over FFI, and call methods that use them from multiple threads. Both Send and Sync are required on the inner type for Arc to implement Send itself, which is what we must guarantee to be able to move an Arc over FFI, since we can't guarantee it is kept on the same thread inside the calling code. --- .../ui/interface_not_sync_and_send.stderr | 18 +++--- .../interface_trait_not_sync_and_send.stderr | 56 +++++++++---------- uniffi_core/src/ffi_converter_traits.rs | 2 +- 3 files changed, 37 insertions(+), 39 deletions(-) diff --git a/fixtures/uitests/tests/ui/interface_not_sync_and_send.stderr b/fixtures/uitests/tests/ui/interface_not_sync_and_send.stderr index 15c5614a00..a443491f41 100644 --- a/fixtures/uitests/tests/ui/interface_not_sync_and_send.stderr +++ b/fixtures/uitests/tests/ui/interface_not_sync_and_send.stderr @@ -11,12 +11,11 @@ note: required because it appears within the type `Counter` | 9 | pub struct Counter { | ^^^^^^^ -note: required by a bound in `_::{closure#0}::assert_impl_all` - --> $OUT_DIR[uniffi_uitests]/counter.uniffi.rs +note: required by a bound in `FfiConverterArc` + --> $WORKSPACE/uniffi_core/src/ffi_converter_traits.rs | - | #[::uniffi::expand_interface_support(tag = crate::UniFfiTag)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all` - = note: this error originates in the macro `uniffi::deps::static_assertions::assert_impl_all` which comes from the expansion of the attribute macro `::uniffi::expand_interface_support` (in Nightly builds, run with -Z macro-backtrace for more info) + | pub unsafe trait FfiConverterArc: Send + Sync { + | ^^^^ required by this bound in `FfiConverterArc` error[E0277]: `Cell` cannot be shared between threads safely --> tests/ui/interface_not_sync_and_send.rs:27:12 @@ -31,9 +30,8 @@ note: required because it appears within the type `ProcMacroCounter` | 27 | pub struct ProcMacroCounter { | ^^^^^^^^^^^^^^^^ -note: required by a bound in `_::{closure#0}::assert_impl_all` - --> tests/ui/interface_not_sync_and_send.rs:26:10 +note: required by a bound in `FfiConverterArc` + --> $WORKSPACE/uniffi_core/src/ffi_converter_traits.rs | -26 | #[derive(uniffi::Object)] - | ^^^^^^^^^^^^^^ required by this bound in `assert_impl_all` - = note: this error originates in the macro `uniffi::deps::static_assertions::assert_impl_all` which comes from the expansion of the derive macro `uniffi::Object` (in Nightly builds, run with -Z macro-backtrace for more info) + | pub unsafe trait FfiConverterArc: Send + Sync { + | ^^^^ required by this bound in `FfiConverterArc` diff --git a/fixtures/uitests/tests/ui/interface_trait_not_sync_and_send.stderr b/fixtures/uitests/tests/ui/interface_trait_not_sync_and_send.stderr index c3d35ec254..80aa7b13d0 100644 --- a/fixtures/uitests/tests/ui/interface_trait_not_sync_and_send.stderr +++ b/fixtures/uitests/tests/ui/interface_trait_not_sync_and_send.stderr @@ -1,55 +1,55 @@ -error[E0277]: `dyn Trait` cannot be shared between threads safely +error[E0277]: `(dyn Trait + 'static)` cannot be shared between threads safely --> $OUT_DIR[uniffi_uitests]/trait.uniffi.rs | | ::uniffi::expand_trait_interface_support!(r#Trait); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Trait` cannot be shared between threads safely + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Trait + 'static)` cannot be shared between threads safely | - = help: the trait `Sync` is not implemented for `dyn Trait` -note: required by a bound in `_::{closure#0}::assert_impl_all` - --> $OUT_DIR[uniffi_uitests]/trait.uniffi.rs + = help: the trait `Sync` is not implemented for `(dyn Trait + 'static)` +note: required by a bound in `FfiConverterArc` + --> $WORKSPACE/uniffi_core/src/ffi_converter_traits.rs | - | ::uniffi::expand_trait_interface_support!(r#Trait); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all` + | pub unsafe trait FfiConverterArc: Send + Sync { + | ^^^^ required by this bound in `FfiConverterArc` = note: this error originates in the macro `::uniffi::expand_trait_interface_support` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0277]: `dyn Trait` cannot be sent between threads safely +error[E0277]: `(dyn Trait + 'static)` cannot be sent between threads safely --> $OUT_DIR[uniffi_uitests]/trait.uniffi.rs | | ::uniffi::expand_trait_interface_support!(r#Trait); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Trait` cannot be sent between threads safely + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Trait + 'static)` cannot be sent between threads safely | - = help: the trait `Send` is not implemented for `dyn Trait` -note: required by a bound in `_::{closure#0}::assert_impl_all` - --> $OUT_DIR[uniffi_uitests]/trait.uniffi.rs + = help: the trait `Send` is not implemented for `(dyn Trait + 'static)` +note: required by a bound in `FfiConverterArc` + --> $WORKSPACE/uniffi_core/src/ffi_converter_traits.rs | - | ::uniffi::expand_trait_interface_support!(r#Trait); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all` + | pub unsafe trait FfiConverterArc: Send + Sync { + | ^^^^ required by this bound in `FfiConverterArc` = note: this error originates in the macro `::uniffi::expand_trait_interface_support` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0277]: `dyn ProcMacroTrait` cannot be shared between threads safely +error[E0277]: `(dyn ProcMacroTrait + 'static)` cannot be shared between threads safely --> tests/ui/interface_trait_not_sync_and_send.rs:11:1 | 11 | #[uniffi::export] - | ^^^^^^^^^^^^^^^^^ `dyn ProcMacroTrait` cannot be shared between threads safely + | ^^^^^^^^^^^^^^^^^ `(dyn ProcMacroTrait + 'static)` cannot be shared between threads safely | - = help: the trait `Sync` is not implemented for `dyn ProcMacroTrait` -note: required by a bound in `_::{closure#0}::assert_impl_all` - --> tests/ui/interface_trait_not_sync_and_send.rs:11:1 + = help: the trait `Sync` is not implemented for `(dyn ProcMacroTrait + 'static)` +note: required by a bound in `FfiConverterArc` + --> $WORKSPACE/uniffi_core/src/ffi_converter_traits.rs | -11 | #[uniffi::export] - | ^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all` + | pub unsafe trait FfiConverterArc: Send + Sync { + | ^^^^ required by this bound in `FfiConverterArc` = note: this error originates in the attribute macro `uniffi::export` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0277]: `dyn ProcMacroTrait` cannot be sent between threads safely +error[E0277]: `(dyn ProcMacroTrait + 'static)` cannot be sent between threads safely --> tests/ui/interface_trait_not_sync_and_send.rs:11:1 | 11 | #[uniffi::export] - | ^^^^^^^^^^^^^^^^^ `dyn ProcMacroTrait` cannot be sent between threads safely + | ^^^^^^^^^^^^^^^^^ `(dyn ProcMacroTrait + 'static)` cannot be sent between threads safely | - = help: the trait `Send` is not implemented for `dyn ProcMacroTrait` -note: required by a bound in `_::{closure#0}::assert_impl_all` - --> tests/ui/interface_trait_not_sync_and_send.rs:11:1 + = help: the trait `Send` is not implemented for `(dyn ProcMacroTrait + 'static)` +note: required by a bound in `FfiConverterArc` + --> $WORKSPACE/uniffi_core/src/ffi_converter_traits.rs | -11 | #[uniffi::export] - | ^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all` + | pub unsafe trait FfiConverterArc: Send + Sync { + | ^^^^ required by this bound in `FfiConverterArc` = note: this error originates in the attribute macro `uniffi::export` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/uniffi_core/src/ffi_converter_traits.rs b/uniffi_core/src/ffi_converter_traits.rs index d7e2e30523..068484f069 100644 --- a/uniffi_core/src/ffi_converter_traits.rs +++ b/uniffi_core/src/ffi_converter_traits.rs @@ -174,7 +174,7 @@ pub unsafe trait FfiConverter: Sized { /// ## Safety /// /// This has the same safety considerations as FfiConverter -pub unsafe trait FfiConverterArc { +pub unsafe trait FfiConverterArc: Send + Sync { type FfiType; type ReturnType: FfiDefault; type FutureCallback: Copy;