From 9d0d9a787b3860c6a5b3b65d409c1564458d2c5d Mon Sep 17 00:00:00 2001 From: Leon Matthes Date: Tue, 1 Oct 2024 17:09:16 +0200 Subject: [PATCH] Fix: Require Send on closures connected to signals The closures may be executed on a different thread, depending on where the emitting object lives. Also closes #577. We have determined that is indeed safe to queue a deferred closure, as the closure will not be called if the object is deleted, as we use the object itself as the context. --- .../src/generator/rust/property/mod.rs | 18 +++---- .../cxx-qt-gen/src/generator/rust/signals.rs | 30 +++++------ .../test_outputs/passthrough_and_naming.rs | 52 +++++++++++-------- crates/cxx-qt-gen/test_outputs/properties.rs | 44 +++++++++------- crates/cxx-qt-gen/test_outputs/signals.rs | 52 +++++++++++-------- 5 files changed, 111 insertions(+), 85 deletions(-) diff --git a/crates/cxx-qt-gen/src/generator/rust/property/mod.rs b/crates/cxx-qt-gen/src/generator/rust/property/mod.rs index 2520fbad4..171f17854 100644 --- a/crates/cxx-qt-gen/src/generator/rust/property/mod.rs +++ b/crates/cxx-qt-gen/src/generator/rust/property/mod.rs @@ -323,7 +323,7 @@ mod tests { #[doc = "Connect the given function pointer to the signal "] #[doc = "trivialPropertyChanged"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_trivial_property_changed, ) + 'static>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType) -> cxx_qt::QMetaObjectConnectionGuard + pub fn connect_trivial_property_changed, ) + 'static + Send>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType) -> cxx_qt::QMetaObjectConnectionGuard { cxx_qt::QMetaObjectConnectionGuard::from(qobject::MyObject_connect_trivial_property_changed( self, @@ -343,7 +343,7 @@ mod tests { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_trivial_property_changed, ) + 'static>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F) -> cxx_qt::QMetaObjectConnectionGuard + pub fn on_trivial_property_changed, ) + 'static + Send>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F) -> cxx_qt::QMetaObjectConnectionGuard { cxx_qt::QMetaObjectConnectionGuard::from(qobject::MyObject_connect_trivial_property_changed( self, @@ -366,7 +366,7 @@ mod tests { parse_quote! { impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for MyObjectCxxQtSignalClosuretrivialPropertyChanged { type Id = cxx::type_id!("::rust::cxxqtgen1::MyObjectCxxQtSignalHandlertrivialPropertyChanged"); - type FnType = dyn FnMut(core::pin::Pin<&mut qobject::MyObject>, ); + type FnType = dyn FnMut(core::pin::Pin<&mut qobject::MyObject>, ) + Send; } }, ); @@ -448,7 +448,7 @@ mod tests { #[doc = "Connect the given function pointer to the signal "] #[doc = "opaquePropertyChanged"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_opaque_property_changed, ) + 'static>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType) -> cxx_qt::QMetaObjectConnectionGuard + pub fn connect_opaque_property_changed, ) + 'static + Send>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType) -> cxx_qt::QMetaObjectConnectionGuard { cxx_qt::QMetaObjectConnectionGuard::from(qobject::MyObject_connect_opaque_property_changed( self, @@ -468,7 +468,7 @@ mod tests { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_opaque_property_changed, ) + 'static>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F) -> cxx_qt::QMetaObjectConnectionGuard + pub fn on_opaque_property_changed, ) + 'static + Send>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F) -> cxx_qt::QMetaObjectConnectionGuard { cxx_qt::QMetaObjectConnectionGuard::from(qobject::MyObject_connect_opaque_property_changed( self, @@ -491,7 +491,7 @@ mod tests { parse_quote! { impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for MyObjectCxxQtSignalClosureopaquePropertyChanged { type Id = cxx::type_id!("::rust::cxxqtgen1::MyObjectCxxQtSignalHandleropaquePropertyChanged"); - type FnType = dyn FnMut(core::pin::Pin<&mut qobject::MyObject>, ); + type FnType = dyn FnMut(core::pin::Pin<&mut qobject::MyObject>, ) + Send; } }, ); @@ -573,7 +573,7 @@ mod tests { #[doc = "Connect the given function pointer to the signal "] #[doc = "unsafePropertyChanged"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_unsafe_property_changed, ) + 'static>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType) -> cxx_qt::QMetaObjectConnectionGuard + pub fn connect_unsafe_property_changed, ) + 'static + Send>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType) -> cxx_qt::QMetaObjectConnectionGuard { cxx_qt::QMetaObjectConnectionGuard::from(qobject::MyObject_connect_unsafe_property_changed( self, @@ -593,7 +593,7 @@ mod tests { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_unsafe_property_changed, ) + 'static>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F) -> cxx_qt::QMetaObjectConnectionGuard + pub fn on_unsafe_property_changed, ) + 'static + Send>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F) -> cxx_qt::QMetaObjectConnectionGuard { cxx_qt::QMetaObjectConnectionGuard::from(qobject::MyObject_connect_unsafe_property_changed( self, @@ -616,7 +616,7 @@ mod tests { parse_quote! { impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for MyObjectCxxQtSignalClosureunsafePropertyChanged { type Id = cxx::type_id!("::rust::cxxqtgen1::MyObjectCxxQtSignalHandlerunsafePropertyChanged"); - type FnType = dyn FnMut(core::pin::Pin<&mut qobject::MyObject>, ); + type FnType = dyn FnMut(core::pin::Pin<&mut qobject::MyObject>, ) + Send; } }, ); diff --git a/crates/cxx-qt-gen/src/generator/rust/signals.rs b/crates/cxx-qt-gen/src/generator/rust/signals.rs index fcc0aa287..ca6262bed 100644 --- a/crates/cxx-qt-gen/src/generator/rust/signals.rs +++ b/crates/cxx-qt-gen/src/generator/rust/signals.rs @@ -164,7 +164,7 @@ pub fn generate_rust_signal( #[doc = "Connect the given function pointer to the signal "] #[doc = #signal_name_cpp] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn #connect_ident_rust(self: #self_type_qualified, mut closure: F, conn_type: cxx_qt::ConnectionType) -> cxx_qt::QMetaObjectConnectionGuard + pub fn #connect_ident_rust(self: #self_type_qualified, mut closure: F, conn_type: cxx_qt::ConnectionType) -> cxx_qt::QMetaObjectConnectionGuard { cxx_qt::QMetaObjectConnectionGuard::from(#module_ident::#free_connect_ident_rust( self, @@ -181,7 +181,7 @@ pub fn generate_rust_signal( #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn #on_ident_rust(self: #self_type_qualified, mut closure: F) -> cxx_qt::QMetaObjectConnectionGuard + pub fn #on_ident_rust(self: #self_type_qualified, mut closure: F) -> cxx_qt::QMetaObjectConnectionGuard { cxx_qt::QMetaObjectConnectionGuard::from(#module_ident::#free_connect_ident_rust( self, @@ -198,7 +198,7 @@ pub fn generate_rust_signal( quote! { impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for #closure_struct { type Id = cxx::type_id!(#signal_handler_alias_namespaced_str); - type FnType = dyn FnMut(#self_type_qualified, #(#parameters_qualified_type),*); + type FnType = dyn FnMut(#self_type_qualified, #(#parameters_qualified_type),*) + Send; } }, quote! { @@ -302,7 +302,7 @@ mod tests { #[doc = "Connect the given function pointer to the signal "] #[doc = "ready"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_ready, ) + 'static>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType) -> cxx_qt::QMetaObjectConnectionGuard + pub fn connect_ready, ) + 'static + Send>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType) -> cxx_qt::QMetaObjectConnectionGuard { cxx_qt::QMetaObjectConnectionGuard::from(qobject::MyObject_connect_ready( self, @@ -322,7 +322,7 @@ mod tests { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_ready, ) + 'static>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F) -> cxx_qt::QMetaObjectConnectionGuard + pub fn on_ready, ) + 'static + Send>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F) -> cxx_qt::QMetaObjectConnectionGuard { cxx_qt::QMetaObjectConnectionGuard::from(qobject::MyObject_connect_ready( self, @@ -345,7 +345,7 @@ mod tests { quote! { impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for MyObjectCxxQtSignalClosureready { type Id = cxx::type_id!("::rust::cxxqtgen1::MyObjectCxxQtSignalHandlerready"); - type FnType = dyn FnMut(core::pin::Pin<&mut qobject::MyObject>, ); + type FnType = dyn FnMut(core::pin::Pin<&mut qobject::MyObject>, ) + Send; } }, ); @@ -475,7 +475,7 @@ mod tests { #[doc = "Connect the given function pointer to the signal "] #[doc = "dataChanged"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_data_changed, i32, cxx::UniquePtr) + 'static>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType) -> cxx_qt::QMetaObjectConnectionGuard + pub fn connect_data_changed, i32, cxx::UniquePtr) + 'static + Send>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType) -> cxx_qt::QMetaObjectConnectionGuard { cxx_qt::QMetaObjectConnectionGuard::from(qobject::MyObject_connect_data_changed( self, @@ -495,7 +495,7 @@ mod tests { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_data_changed, i32, cxx::UniquePtr) + 'static>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F) -> cxx_qt::QMetaObjectConnectionGuard + pub fn on_data_changed, i32, cxx::UniquePtr) + 'static + Send>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F) -> cxx_qt::QMetaObjectConnectionGuard { cxx_qt::QMetaObjectConnectionGuard::from(qobject::MyObject_connect_data_changed( self, @@ -518,7 +518,7 @@ mod tests { quote! { impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for MyObjectCxxQtSignalClosuredataChanged { type Id = cxx::type_id!("::rust::cxxqtgen1::MyObjectCxxQtSignalHandlerdataChanged"); - type FnType = dyn FnMut(core::pin::Pin<&mut qobject::MyObject>, i32, cxx::UniquePtr); + type FnType = dyn FnMut(core::pin::Pin<&mut qobject::MyObject>, i32, cxx::UniquePtr) + Send; } }, ); @@ -616,7 +616,7 @@ mod tests { #[doc = "Connect the given function pointer to the signal "] #[doc = "unsafeSignal"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_unsafe_signal, *mut T) + 'static>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType) -> cxx_qt::QMetaObjectConnectionGuard + pub fn connect_unsafe_signal, *mut T) + 'static +Send>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType) -> cxx_qt::QMetaObjectConnectionGuard { cxx_qt::QMetaObjectConnectionGuard::from(qobject::MyObject_connect_unsafe_signal( self, @@ -636,7 +636,7 @@ mod tests { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_unsafe_signal, *mut T) + 'static>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F) -> cxx_qt::QMetaObjectConnectionGuard + pub fn on_unsafe_signal, *mut T) + 'static + Send>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F) -> cxx_qt::QMetaObjectConnectionGuard { cxx_qt::QMetaObjectConnectionGuard::from(qobject::MyObject_connect_unsafe_signal( self, @@ -659,7 +659,7 @@ mod tests { quote! { impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for MyObjectCxxQtSignalClosureunsafeSignal { type Id = cxx::type_id!("::rust::cxxqtgen1::MyObjectCxxQtSignalHandlerunsafeSignal"); - type FnType = dyn FnMut(core::pin::Pin<&mut qobject::MyObject>, *mut T); + type FnType = dyn FnMut(core::pin::Pin<&mut qobject::MyObject>, *mut T) + Send; } }, ); @@ -759,7 +759,7 @@ mod tests { #[doc = "Connect the given function pointer to the signal "] #[doc = "baseName"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_existing_signal, ) + 'static>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType) -> cxx_qt::QMetaObjectConnectionGuard + pub fn connect_existing_signal, ) + 'static + Send>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType) -> cxx_qt::QMetaObjectConnectionGuard { cxx_qt::QMetaObjectConnectionGuard::from(qobject::MyObject_connect_existing_signal( self, @@ -779,7 +779,7 @@ mod tests { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_existing_signal, ) + 'static>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F) -> cxx_qt::QMetaObjectConnectionGuard + pub fn on_existing_signal, ) + 'static + Send>(self: core::pin::Pin<&mut qobject::MyObject>, mut closure: F) -> cxx_qt::QMetaObjectConnectionGuard { cxx_qt::QMetaObjectConnectionGuard::from(qobject::MyObject_connect_existing_signal( self, @@ -802,7 +802,7 @@ mod tests { quote! { impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for MyObjectCxxQtSignalClosurebaseName { type Id = cxx::type_id!("::rust::cxxqtgen1::MyObjectCxxQtSignalHandlerbaseName"); - type FnType = dyn FnMut(core::pin::Pin<&mut qobject::MyObject>, ); + type FnType = dyn FnMut(core::pin::Pin<&mut qobject::MyObject>, ) + Send; } }, ); diff --git a/crates/cxx-qt-gen/test_outputs/passthrough_and_naming.rs b/crates/cxx-qt-gen/test_outputs/passthrough_and_naming.rs index de00d8f9e..45ee82557 100644 --- a/crates/cxx-qt-gen/test_outputs/passthrough_and_naming.rs +++ b/crates/cxx-qt-gen/test_outputs/passthrough_and_naming.rs @@ -462,7 +462,9 @@ impl ffi::MyObject { #[doc = "Connect the given function pointer to the signal "] #[doc = "propertyNameChanged"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_property_name_changed) + 'static>( + pub fn connect_property_name_changed< + F: FnMut(core::pin::Pin<&mut ffi::MyObject>) + 'static + Send, + >( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType, @@ -482,7 +484,9 @@ impl ffi::MyObject { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_property_name_changed) + 'static>( + pub fn on_property_name_changed< + F: FnMut(core::pin::Pin<&mut ffi::MyObject>) + 'static + Send, + >( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, ) -> cxx_qt::QMetaObjectConnectionGuard { @@ -503,7 +507,7 @@ impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure type Id = cxx::type_id!( "::cxx_qt::multi_object::rust::cxxqtgen1::MyObjectCxxQtSignalHandlerpropertyNameChanged" ); - type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>); + type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>) + Send; } use core::mem::drop as drop_MyObject_signal_handler_propertyNameChanged; fn call_MyObject_signal_handler_propertyNameChanged( @@ -526,7 +530,7 @@ impl ffi::MyObject { #[doc = "Connect the given function pointer to the signal "] #[doc = "ready"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_ready) + 'static>( + pub fn connect_ready) + 'static + Send>( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType, @@ -546,7 +550,7 @@ impl ffi::MyObject { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_ready) + 'static>( + pub fn on_ready) + 'static + Send>( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, ) -> cxx_qt::QMetaObjectConnectionGuard { @@ -564,7 +568,7 @@ pub struct MyObjectCxxQtSignalClosureready {} impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for MyObjectCxxQtSignalClosureready { type Id = cxx::type_id!("::cxx_qt::multi_object::rust::cxxqtgen1::MyObjectCxxQtSignalHandlerready"); - type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>); + type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>) + Send; } use core::mem::drop as drop_MyObject_signal_handler_ready; fn call_MyObject_signal_handler_ready( @@ -624,7 +628,7 @@ impl ffi::SecondObject { #[doc = "propertyNameChanged"] #[doc = ", so that when the signal is emitted the function pointer is executed."] pub fn connect_property_name_changed< - F: FnMut(core::pin::Pin<&mut ffi::SecondObject>) + 'static, + F: FnMut(core::pin::Pin<&mut ffi::SecondObject>) + 'static + Send, >( self: core::pin::Pin<&mut ffi::SecondObject>, mut closure: F, @@ -645,7 +649,9 @@ impl ffi::SecondObject { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_property_name_changed) + 'static>( + pub fn on_property_name_changed< + F: FnMut(core::pin::Pin<&mut ffi::SecondObject>) + 'static + Send, + >( self: core::pin::Pin<&mut ffi::SecondObject>, mut closure: F, ) -> cxx_qt::QMetaObjectConnectionGuard { @@ -666,7 +672,7 @@ impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure type Id = cxx::type_id!( "::second_object::rust::cxxqtgen1::SecondObjectCxxQtSignalHandlerpropertyNameChanged" ); - type FnType = dyn FnMut(core::pin::Pin<&mut ffi::SecondObject>); + type FnType = dyn FnMut(core::pin::Pin<&mut ffi::SecondObject>) + Send; } use core::mem::drop as drop_SecondObject_signal_handler_propertyNameChanged; fn call_SecondObject_signal_handler_propertyNameChanged( @@ -689,7 +695,7 @@ impl ffi::SecondObject { #[doc = "Connect the given function pointer to the signal "] #[doc = "ready"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_ready) + 'static>( + pub fn connect_ready) + 'static + Send>( self: core::pin::Pin<&mut ffi::SecondObject>, mut closure: F, conn_type: cxx_qt::ConnectionType, @@ -709,7 +715,7 @@ impl ffi::SecondObject { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_ready) + 'static>( + pub fn on_ready) + 'static + Send>( self: core::pin::Pin<&mut ffi::SecondObject>, mut closure: F, ) -> cxx_qt::QMetaObjectConnectionGuard { @@ -727,7 +733,7 @@ pub struct SecondObjectCxxQtSignalClosureready {} impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for SecondObjectCxxQtSignalClosureready { type Id = cxx::type_id!("::second_object::rust::cxxqtgen1::SecondObjectCxxQtSignalHandlerready"); - type FnType = dyn FnMut(core::pin::Pin<&mut ffi::SecondObject>); + type FnType = dyn FnMut(core::pin::Pin<&mut ffi::SecondObject>) + Send; } use core::mem::drop as drop_SecondObject_signal_handler_ready; fn call_SecondObject_signal_handler_ready( @@ -786,7 +792,9 @@ impl ffi::QPushButton { #[doc = "Connect the given function pointer to the signal "] #[doc = "clicked"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_clicked, bool) + 'static>( + pub fn connect_clicked< + F: FnMut(core::pin::Pin<&mut ffi::QPushButton>, bool) + 'static + Send, + >( self: core::pin::Pin<&mut ffi::QPushButton>, mut closure: F, conn_type: cxx_qt::ConnectionType, @@ -806,7 +814,7 @@ impl ffi::QPushButton { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_clicked, bool) + 'static>( + pub fn on_clicked, bool) + 'static + Send>( self: core::pin::Pin<&mut ffi::QPushButton>, mut closure: F, ) -> cxx_qt::QMetaObjectConnectionGuard { @@ -825,7 +833,7 @@ impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for QPushButtonCxxQtSignal type Id = cxx::type_id!( "::cxx_qt::multi_object::rust::cxxqtgen1::QPushButtonCxxQtSignalHandlerclicked" ); - type FnType = dyn FnMut(core::pin::Pin<&mut ffi::QPushButton>, bool); + type FnType = dyn FnMut(core::pin::Pin<&mut ffi::QPushButton>, bool) + Send; } use core::mem::drop as drop_QPushButton_signal_handler_clicked; fn call_QPushButton_signal_handler_clicked( @@ -847,7 +855,7 @@ impl ffi::ExternObject { #[doc = "Connect the given function pointer to the signal "] #[doc = "dataReady"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_data_ready) + 'static>( + pub fn connect_data_ready) + 'static + Send>( self: core::pin::Pin<&mut ffi::ExternObject>, mut closure: F, conn_type: cxx_qt::ConnectionType, @@ -861,7 +869,7 @@ impl ffi::ExternObject { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_data_ready) + 'static>( + pub fn on_data_ready) + 'static + Send>( self: core::pin::Pin<&mut ffi::ExternObject>, mut closure: F, ) -> cxx_qt::QMetaObjectConnectionGuard { @@ -873,7 +881,7 @@ pub struct ExternObjectCxxQtSignalClosuredataReady {} impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for ExternObjectCxxQtSignalClosuredataReady { type Id = cxx::type_id!("::mynamespace::rust::cxxqtgen1::ExternObjectCxxQtSignalHandlerdataReady"); - type FnType = dyn FnMut(core::pin::Pin<&mut ffi::ExternObject>); + type FnType = dyn FnMut(core::pin::Pin<&mut ffi::ExternObject>) + Send; } use core::mem::drop as drop_ExternObject_signal_handler_dataReady; fn call_ExternObject_signal_handler_dataReady( @@ -896,7 +904,9 @@ impl ffi::ExternObject { #[doc = "Connect the given function pointer to the signal "] #[doc = "errorOccurred"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_error_occurred) + 'static>( + pub fn connect_error_occurred< + F: FnMut(core::pin::Pin<&mut ffi::ExternObject>) + 'static + Send, + >( self: core::pin::Pin<&mut ffi::ExternObject>, mut closure: F, conn_type: cxx_qt::ConnectionType, @@ -918,7 +928,7 @@ impl ffi::ExternObject { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_error_occurred) + 'static>( + pub fn on_error_occurred) + 'static + Send>( self: core::pin::Pin<&mut ffi::ExternObject>, mut closure: F, ) -> cxx_qt::QMetaObjectConnectionGuard { @@ -941,7 +951,7 @@ impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure type Id = cxx::type_id!( "::mynamespace::rust::cxxqtgen1::ExternObjectCxxQtSignalHandlererrorOccurred" ); - type FnType = dyn FnMut(core::pin::Pin<&mut ffi::ExternObject>); + type FnType = dyn FnMut(core::pin::Pin<&mut ffi::ExternObject>) + Send; } use core::mem::drop as drop_ExternObject_signal_handler_errorOccurred; fn call_ExternObject_signal_handler_errorOccurred( diff --git a/crates/cxx-qt-gen/test_outputs/properties.rs b/crates/cxx-qt-gen/test_outputs/properties.rs index 0d2f7ecd3..a91add2e3 100644 --- a/crates/cxx-qt-gen/test_outputs/properties.rs +++ b/crates/cxx-qt-gen/test_outputs/properties.rs @@ -528,7 +528,9 @@ impl ffi::MyObject { #[doc = "Connect the given function pointer to the signal "] #[doc = "primitiveChanged"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_primitive_changed) + 'static>( + pub fn connect_primitive_changed< + F: FnMut(core::pin::Pin<&mut ffi::MyObject>) + 'static + Send, + >( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType, @@ -550,7 +552,7 @@ impl ffi::MyObject { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_primitive_changed) + 'static>( + pub fn on_primitive_changed) + 'static + Send>( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, ) -> cxx_qt::QMetaObjectConnectionGuard { @@ -573,7 +575,7 @@ impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure type Id = cxx::type_id!( "::cxx_qt::my_object::rust::cxxqtgen1::MyObjectCxxQtSignalHandlerprimitiveChanged" ); - type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>); + type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>) + Send; } use core::mem::drop as drop_MyObject_signal_handler_primitiveChanged; fn call_MyObject_signal_handler_primitiveChanged( @@ -596,7 +598,9 @@ impl ffi::MyObject { #[doc = "Connect the given function pointer to the signal "] #[doc = "trivialChanged"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_trivial_changed) + 'static>( + pub fn connect_trivial_changed< + F: FnMut(core::pin::Pin<&mut ffi::MyObject>) + 'static + Send, + >( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType, @@ -610,7 +614,7 @@ impl ffi::MyObject { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_trivial_changed) + 'static>( + pub fn on_trivial_changed) + 'static + Send>( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, ) -> cxx_qt::QMetaObjectConnectionGuard { @@ -623,7 +627,7 @@ impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for MyObjectCxxQtSignalClo type Id = cxx::type_id!( "::cxx_qt::my_object::rust::cxxqtgen1::MyObjectCxxQtSignalHandlertrivialChanged" ); - type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>); + type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>) + Send; } use core::mem::drop as drop_MyObject_signal_handler_trivialChanged; fn call_MyObject_signal_handler_trivialChanged( @@ -647,7 +651,7 @@ impl ffi::MyObject { #[doc = "customFunctionPropChanged"] #[doc = ", so that when the signal is emitted the function pointer is executed."] pub fn connect_custom_function_prop_changed< - F: FnMut(core::pin::Pin<&mut ffi::MyObject>) + 'static, + F: FnMut(core::pin::Pin<&mut ffi::MyObject>) + 'static + Send, >( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, @@ -671,7 +675,7 @@ impl ffi::MyObject { #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] pub fn on_custom_function_prop_changed< - F: FnMut(core::pin::Pin<&mut ffi::MyObject>) + 'static, + F: FnMut(core::pin::Pin<&mut ffi::MyObject>) + 'static + Send, >( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, @@ -695,7 +699,7 @@ impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure type Id = cxx::type_id!( "::cxx_qt::my_object::rust::cxxqtgen1::MyObjectCxxQtSignalHandlercustomFunctionPropChanged" ); - type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>); + type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>) + Send; } use core::mem::drop as drop_MyObject_signal_handler_customFunctionPropChanged; fn call_MyObject_signal_handler_customFunctionPropChanged( @@ -719,7 +723,7 @@ impl ffi::MyObject { #[doc = "renamedPropertyChanged"] #[doc = ", so that when the signal is emitted the function pointer is executed."] pub fn connect_renamed_property_changed< - F: FnMut(core::pin::Pin<&mut ffi::MyObject>) + 'static, + F: FnMut(core::pin::Pin<&mut ffi::MyObject>) + 'static + Send, >( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, @@ -740,7 +744,9 @@ impl ffi::MyObject { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_renamed_property_changed) + 'static>( + pub fn on_renamed_property_changed< + F: FnMut(core::pin::Pin<&mut ffi::MyObject>) + 'static + Send, + >( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, ) -> cxx_qt::QMetaObjectConnectionGuard { @@ -761,7 +767,7 @@ impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure type Id = cxx::type_id!( "::cxx_qt::my_object::rust::cxxqtgen1::MyObjectCxxQtSignalHandlerrenamedPropertyChanged" ); - type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>); + type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>) + Send; } use core::mem::drop as drop_MyObject_signal_handler_renamedPropertyChanged; fn call_MyObject_signal_handler_renamedPropertyChanged( @@ -785,7 +791,7 @@ impl ffi::MyObject { #[doc = "named_prop_2Changed"] #[doc = ", so that when the signal is emitted the function pointer is executed."] pub fn connect_renamed_property_2_changed< - F: FnMut(core::pin::Pin<&mut ffi::MyObject>) + 'static, + F: FnMut(core::pin::Pin<&mut ffi::MyObject>) + 'static + Send, >( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, @@ -806,7 +812,9 @@ impl ffi::MyObject { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_renamed_property_2_changed) + 'static>( + pub fn on_renamed_property_2_changed< + F: FnMut(core::pin::Pin<&mut ffi::MyObject>) + 'static + Send, + >( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, ) -> cxx_qt::QMetaObjectConnectionGuard { @@ -827,7 +835,7 @@ impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure type Id = cxx::type_id!( "::cxx_qt::my_object::rust::cxxqtgen1::MyObjectCxxQtSignalHandlernamed_prop_2Changed" ); - type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>); + type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>) + Send; } use core::mem::drop as drop_MyObject_signal_handler_named_prop_2Changed; fn call_MyObject_signal_handler_named_prop_2Changed( @@ -850,7 +858,7 @@ impl ffi::MyObject { #[doc = "Connect the given function pointer to the signal "] #[doc = "myOnChanged"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_my_on_changed) + 'static>( + pub fn connect_my_on_changed) + 'static + Send>( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType, @@ -870,7 +878,7 @@ impl ffi::MyObject { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_my_on_changed) + 'static>( + pub fn on_my_on_changed) + 'static + Send>( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, ) -> cxx_qt::QMetaObjectConnectionGuard { @@ -889,7 +897,7 @@ impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for MyObjectCxxQtSignalClo type Id = cxx::type_id!( "::cxx_qt::my_object::rust::cxxqtgen1::MyObjectCxxQtSignalHandlermyOnChanged" ); - type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>); + type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>) + Send; } use core::mem::drop as drop_MyObject_signal_handler_myOnChanged; fn call_MyObject_signal_handler_myOnChanged( diff --git a/crates/cxx-qt-gen/test_outputs/signals.rs b/crates/cxx-qt-gen/test_outputs/signals.rs index 88007d63d..01dbf48d2 100644 --- a/crates/cxx-qt-gen/test_outputs/signals.rs +++ b/crates/cxx-qt-gen/test_outputs/signals.rs @@ -204,7 +204,7 @@ impl ffi::MyObject { #[doc = "Connect the given function pointer to the signal "] #[doc = "ready"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_ready) + 'static>( + pub fn connect_ready) + 'static + Send>( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, conn_type: cxx_qt::ConnectionType, @@ -224,7 +224,7 @@ impl ffi::MyObject { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_ready) + 'static>( + pub fn on_ready) + 'static + Send>( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, ) -> cxx_qt::QMetaObjectConnectionGuard { @@ -242,7 +242,7 @@ pub struct MyObjectCxxQtSignalClosureready {} impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for MyObjectCxxQtSignalClosureready { type Id = cxx::type_id!("::cxx_qt::my_object::rust::cxxqtgen1::MyObjectCxxQtSignalHandlerready"); - type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>); + type FnType = dyn FnMut(core::pin::Pin<&mut ffi::MyObject>) + Send; } use core::mem::drop as drop_MyObject_signal_handler_ready; fn call_MyObject_signal_handler_ready( @@ -270,7 +270,9 @@ impl ffi::MyObject { cxx::UniquePtr, ffi::QPoint, &ffi::QPoint, - ) + 'static, + ) + + 'static + + Send, >( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, @@ -298,7 +300,9 @@ impl ffi::MyObject { cxx::UniquePtr, ffi::QPoint, &ffi::QPoint, - ) + 'static, + ) + + 'static + + Send, >( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, @@ -319,12 +323,12 @@ impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for MyObjectCxxQtSignalClo "::cxx_qt::my_object::rust::cxxqtgen1::MyObjectCxxQtSignalHandlerdataChanged" ); type FnType = dyn FnMut( - core::pin::Pin<&mut ffi::MyObject>, - i32, - cxx::UniquePtr, - ffi::QPoint, - &ffi::QPoint, - ); + core::pin::Pin<&mut ffi::MyObject>, + i32, + cxx::UniquePtr, + ffi::QPoint, + &ffi::QPoint, + ) + Send; } use core::mem::drop as drop_MyObject_signal_handler_dataChanged; fn call_MyObject_signal_handler_dataChanged( @@ -356,7 +360,9 @@ impl ffi::MyObject { cxx::UniquePtr, ffi::QPoint, &'a ffi::QPoint, - ) + 'static, + ) + + 'static + + Send, >( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, @@ -384,7 +390,9 @@ impl ffi::MyObject { cxx::UniquePtr, ffi::QPoint, &'a ffi::QPoint, - ) + 'static, + ) + + 'static + + Send, >( self: core::pin::Pin<&mut ffi::MyObject>, mut closure: F, @@ -404,12 +412,12 @@ impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for MyObjectCxxQtSignalClo type Id = cxx::type_id!("::cxx_qt::my_object::rust::cxxqtgen1::MyObjectCxxQtSignalHandlernewData"); type FnType = dyn FnMut( - core::pin::Pin<&mut ffi::MyObject>, - i32, - cxx::UniquePtr, - ffi::QPoint, - &'a ffi::QPoint, - ); + core::pin::Pin<&mut ffi::MyObject>, + i32, + cxx::UniquePtr, + ffi::QPoint, + &'a ffi::QPoint, + ) + Send; } use core::mem::drop as drop_MyObject_signal_handler_newData; fn call_MyObject_signal_handler_newData( @@ -453,7 +461,7 @@ impl ffi::QTimer { #[doc = "Connect the given function pointer to the signal "] #[doc = "timeout"] #[doc = ", so that when the signal is emitted the function pointer is executed."] - pub fn connect_timeout) + 'static>( + pub fn connect_timeout) + 'static + Send>( self: core::pin::Pin<&mut ffi::QTimer>, mut closure: F, conn_type: cxx_qt::ConnectionType, @@ -473,7 +481,7 @@ impl ffi::QTimer { #[doc = ", so that when the signal is emitted the function pointer is executed."] #[doc = "\n"] #[doc = "Note that this method uses a AutoConnection connection type."] - pub fn on_timeout) + 'static>( + pub fn on_timeout) + 'static + Send>( self: core::pin::Pin<&mut ffi::QTimer>, mut closure: F, ) -> cxx_qt::QMetaObjectConnectionGuard { @@ -491,7 +499,7 @@ pub struct QTimerCxxQtSignalClosuretimeout {} impl cxx_qt::signalhandler::CxxQtSignalHandlerClosure for QTimerCxxQtSignalClosuretimeout { type Id = cxx::type_id!("::cxx_qt::my_object::rust::cxxqtgen1::QTimerCxxQtSignalHandlertimeout"); - type FnType = dyn FnMut(core::pin::Pin<&mut ffi::QTimer>); + type FnType = dyn FnMut(core::pin::Pin<&mut ffi::QTimer>) + Send; } use core::mem::drop as drop_QTimer_signal_handler_timeout; fn call_QTimer_signal_handler_timeout(