From 47d82d42a91508166024dfd101a13a1eb95f0b79 Mon Sep 17 00:00:00 2001 From: Googler Date: Wed, 29 Apr 2026 01:10:59 -0700 Subject: [PATCH] Add support for unsafe constructor bindings in Crubit. PiperOrigin-RevId: 907425721 --- examples/cpp/virtual/example_generated.rs | 8 +- .../database/function_types.rs | 14 +- .../generate_bindings/generate_function.rs | 128 ++++++++++++++---- .../generate_function_test.rs | 95 +++++++++++-- .../generate_function_thunk.rs | 6 +- .../struct_with_lifetimebound_rs_api.rs | 70 +++++----- .../test/golden/inheritance_rs_api.rs | 12 +- .../test/golden/no_elided_lifetimes_rs_api.rs | 4 +- .../test/golden/no_unique_address_rs_api.rs | 8 +- .../test/golden/nontrivial_type_rs_api.rs | 52 +++---- .../test/golden/operators_rs_api.rs | 4 +- .../test/golden/polymorphic_rs_api.rs | 12 +- .../test/golden/unions_rs_api.rs | 6 +- .../test/golden/user_of_base_class_rs_api.rs | 10 +- .../test/operators/operators_index_rs_api.rs | 71 +++++++--- .../operators/operators_index_rs_api_impl.cc | 7 + .../test/references/references_api_impl.cc | 10 ++ .../test/references/references_rs_api.rs | 74 ++++++---- .../test/struct/constructors/constructors.h | 5 + .../constructors/constructors_api_impl.cc | 10 ++ .../constructors/constructors_rs_api.rs | 70 +++++++++- .../test/struct/constructors/test.rs | 14 +- .../default_member_functions_rs_api.rs | 10 +- .../inheritance/inherited_methods_rs_api.rs | 6 +- .../test/types_only/types_only_rs_api.rs | 20 +-- .../wrapper/impl_ctor/impl_ctor_rs_api.rs | 12 +- support/ctor.rs | 32 +++++ 27 files changed, 564 insertions(+), 206 deletions(-) diff --git a/examples/cpp/virtual/example_generated.rs b/examples/cpp/virtual/example_generated.rs index 16417a6d8..9ab18dc7a 100644 --- a/examples/cpp/virtual/example_generated.rs +++ b/examples/cpp/virtual/example_generated.rs @@ -62,9 +62,9 @@ impl<'__unelided> ::ctor::CtorNew<::ctor::RvalueReference<'__unelided, Self>> fo fn ctor_new(args: ::ctor::RvalueReference<'__unelided, Self>) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN11RustDerivedC1EOS_( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, __param_0, ); }) @@ -107,9 +107,9 @@ impl ::ctor::CtorNew<::definition::RustDerived> for RustDerived { fn ctor_new(args: ::definition::RustDerived) -> Self::CtorType { let mut rust = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN11RustDerivedC1EN10definition11RustDerivedE( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, &mut rust, ); }) diff --git a/rs_bindings_from_cc/generate_bindings/database/function_types.rs b/rs_bindings_from_cc/generate_bindings/database/function_types.rs index b5cb199c5..4a37de8bf 100644 --- a/rs_bindings_from_cc/generate_bindings/database/function_types.rs +++ b/rs_bindings_from_cc/generate_bindings/database/function_types.rs @@ -46,6 +46,10 @@ pub enum TraitName { CtorNew(Rc<[RsTypeKind]>), Default, From(Rc<[RsTypeKind]>), + /// The constructor trait for !Unpin types that are considered unsafe. + UnsafeCtorNew(Rc<[RsTypeKind]>), + /// The conversion trait for Unpin types that are considered unsafe. + UnsafeFrom(Rc<[RsTypeKind]>), /// The PartialEq trait. PartialEq { param: Rc, @@ -88,6 +92,8 @@ impl TraitName { TraitName::CtorNew { .. } => "CtorNew", TraitName::Default => "Default", TraitName::From { .. } => "From", + TraitName::UnsafeCtorNew { .. } => "UnsafeCtorNew", + TraitName::UnsafeFrom { .. } => "UnsafeFrom", TraitName::PartialEq { .. } => "PartialEq", TraitName::PartialOrd { .. } => "PartialOrd", TraitName::CcIndex { .. } => "CcIndex", @@ -101,7 +107,11 @@ impl TraitName { fn params(&self) -> &[RsTypeKind] { match self { Self::Clone | Self::Default | Self::Delete => &[], - Self::CtorNew(params) | Self::From(params) | Self::Other { params, .. } => params, + Self::CtorNew(params) + | Self::From(params) + | Self::UnsafeCtorNew(params) + | Self::UnsafeFrom(params) + | Self::Other { params, .. } => params, Self::PartialEq { param, .. } | Self::PartialOrd { param } => { core::slice::from_ref(param) } @@ -212,6 +222,8 @@ impl ImplKind { Self::None { is_unsafe: true, .. } | Self::Struct { is_unsafe: true, .. } | Self::Trait { trait_name: TraitName::Other { is_unsafe_fn: true, .. }, .. } + | Self::Trait { trait_name: TraitName::UnsafeCtorNew(_), .. } + | Self::Trait { trait_name: TraitName::UnsafeFrom(_), .. } ) } } diff --git a/rs_bindings_from_cc/generate_bindings/generate_function.rs b/rs_bindings_from_cc/generate_bindings/generate_function.rs index ad5fe3be7..391e2cb37 100644 --- a/rs_bindings_from_cc/generate_bindings/generate_function.rs +++ b/rs_bindings_from_cc/generate_bindings/generate_function.rs @@ -62,6 +62,16 @@ fn trait_name_to_token_stream_removing_trait_record( format_tuple_except_singleton_replacing_by_self(db, arg_types, self_type); quote! { From < #formatted_arg_types > } } + UnsafeCtorNew(arg_types) => { + let formatted_arg_types = + format_tuple_except_singleton_replacing_by_self(db, arg_types, self_type); + quote! { ::ctor::UnsafeCtorNew < #formatted_arg_types > } + } + UnsafeFrom(arg_types) => { + let formatted_arg_types = + format_tuple_except_singleton_replacing_by_self(db, arg_types, self_type); + quote! { ::ctor::UnsafeFrom < #formatted_arg_types > } + } PartialEq { param, .. } => { if self_type.is_some_and(|self_type| param.as_ref() == self_type) { quote! {PartialEq} @@ -430,7 +440,7 @@ fn generate_cc_operator_index_nonmut_impls( (*pointer_data.pointee_type).clone() } - other_variant => { + _ => { bail_to_errors!( errors, "operator[] should return a reference (values are not yet supported), found {}", @@ -487,7 +497,7 @@ fn generate_cc_operator_index_mut_impls( (*pointer_data.pointee_type).clone() } - other_variant => { + _ => { bail_to_errors!( errors, "(mutable) operator[] should return a reference (values are not yet supported), found {}", @@ -931,18 +941,20 @@ fn api_func_shape_for_destructor( } /// Issue any errors related to unsafe constructors being unsupported. +/// Returns the unsafe parameters if any, instead of adding errors, when appropriate. fn issue_unsafe_constructor_errors( db: &BindingsGenerator, func: &Func, record: &Record, param_types: &[RsTypeKind], errors: &Errors, -) { +) -> Option { match func.safety_annotation { - SafetyAnnotation::DisableUnsafe => {} + SafetyAnnotation::DisableUnsafe => None, SafetyAnnotation::Unsafe => { errors.add(anyhow!( "Constructors cannot be `unsafe`, but an explicit unsafe annotation was provided. See b/216648347.")); + None } SafetyAnnotation::Unannotated => { // Move and copy constructors are excepted from this check, as Google C++ style @@ -950,7 +962,7 @@ fn issue_unsafe_constructor_errors( // fields of the source object. let is_move_or_copy_ctor = matches!(param_types, [_this, arg] if arg.is_ref_to(record)); if is_move_or_copy_ctor { - return; + return None; } // We skip the first parameter because it's the implicit `this` parameter. @@ -966,10 +978,9 @@ fn issue_unsafe_constructor_errors( .collect::>() .join(""); if !unsafe_params.is_empty() { - errors.add(anyhow!( - "Constructors cannot be `unsafe`, but this constructor accepts:{unsafe_params}" - )); + return Some(unsafe_params); } + None } } } @@ -988,11 +999,9 @@ fn api_func_shape_for_constructor( errors.add(err); } materialize_ctor_in_caller(func, param_types); - issue_unsafe_constructor_errors(db, func, record, param_types, errors); + let unsafe_params = issue_unsafe_constructor_errors(db, func, record, param_types, errors); if !record.is_unpin() { - let func_name = make_rs_ident("ctor_new"); - let [_this, params @ ..] = param_types else { errors.add(anyhow!( "This is a bug in Crubit. Could not find `__this` parameter in a constructor: {:?}", @@ -1021,9 +1030,16 @@ fn api_func_shape_for_constructor( } } } + + let trait_name = if unsafe_params.is_some() { + TraitName::UnsafeCtorNew(params.iter().cloned().collect()) + } else { + TraitName::CtorNew(params.iter().cloned().collect()) + }; + let impl_kind = ImplKind::Trait { record: record.clone(), - trait_name: TraitName::CtorNew(params.iter().cloned().collect()), + trait_name, impl_for: ImplFor::T, format_first_param_as_self: false, drop_return: false, @@ -1033,8 +1049,20 @@ fn api_func_shape_for_constructor( // meaning it's only usable within the current target anyway. always_public: true, }; + return Some((make_rs_ident("ctor_new"), impl_kind)); + } + + if unsafe_params.is_some() { + let func_name = make_rs_ident("unsafe_from"); + let impl_kind = ImplKind::new_trait( + TraitName::UnsafeFrom(Rc::from(param_types[1..].to_vec())), + record.clone(), + /* format_first_param_as_self= */ false, + /* force_const_reference_params= */ false, + ); return Some((func_name, impl_kind)); } + match func.params.len() { 0 => { errors.add(anyhow!( @@ -1386,9 +1414,9 @@ fn generate_func_body( PassingConvention::Ctor => { quote! { ::ctor::FnCtor::new( - move |dest: *mut #return_type_or_self| { + move |__crubit_dest: *mut #return_type_or_self| { #crate_root_path::detail::#thunk_ident( - dest as *mut ::core::ffi::c_void + __crubit_dest as *mut ::core::ffi::c_void #( , #thunk_args )* ); } @@ -1758,14 +1786,17 @@ pub fn generate_function( quoted_return_type = quote! {}; } - if !errors.is_empty() { - if let ImplKind::Trait { trait_name: TraitName::CtorNew(_), .. } = impl_kind { - // Generated CtorNew functions return an `impl Trait` type which can't use - // the `errors_as_unsatisfied_trait_bound` reporting system because - // the `'error` lifetime causes an error when combined with `impl Trait due to - // https://github.com/rust-lang/rust/issues/134804 - errors.consolidate()?; - } + if !errors.is_empty() + && let ImplKind::Trait { + trait_name: TraitName::CtorNew(_) | TraitName::UnsafeCtorNew(_), + .. + } = impl_kind + { + // Generated CtorNew and UnsafeCtorNew functions return an `impl Trait` type which can't use + // the `errors_as_unsatisfied_trait_bound` reporting system because + // the `'error` lifetime causes an error when combined with `impl Trait due to + // https://github.com/rust-lang/rust/issues/134804 + errors.consolidate()?; } let reportable_status: Result<(), ErrorList> = errors.consolidate(); @@ -2159,7 +2190,7 @@ pub fn generate_function( } else { quote! {} }; - if matches!(trait_name, TraitName::CtorNew(_)) { + if matches!(trait_name, TraitName::CtorNew(_) | TraitName::UnsafeCtorNew(_)) { extra_body.extend(quote! { type Error = ::ctor::Infallible; }); @@ -2210,6 +2241,24 @@ pub fn generate_function( } } } + TraitName::UnsafeCtorNew(params) if params.len() == 1 => { + let single_param_ = format_tuple_except_singleton_replacing_by_self( + db, + params, + Some(&self_type_for_extra), + ); + quote! { + impl #formatted_trait_generic_params ::ctor::UnsafeCtorNew<(#single_param_,)> for #record_name #trait_record_param_tokens #unsatisfied_where_clause { + #extra_body + + #[inline (always)] + unsafe fn ctor_new(args: (#single_param_,)) -> Self::CtorType { + let (arg,) = args; + >::ctor_new(arg) + } + } + } + } TraitName::From(params) if reportable_status.is_ok() => { let single_param_ = format_tuple_except_singleton_replacing_by_self( db, @@ -2228,6 +2277,24 @@ pub fn generate_function( } } } + TraitName::UnsafeFrom(params) if reportable_status.is_ok() => { + let single_param_ = format_tuple_except_singleton_replacing_by_self( + db, + params, + Some(&self_type_for_extra), + ); + quote! { + impl #formatted_trait_generic_params ::ctor::UnsafeCtorNew<#single_param_> for #record_name #trait_record_param_tokens #unsatisfied_where_clause { + type CtorType = Self; + type Error = ::ctor::Infallible; + + #[inline (always)] + unsafe fn ctor_new(args: #single_param_) -> Self::CtorType { + >::unsafe_from(args) + } + } + } + } TraitName::CcIndex { .. } | TraitName::CcIndexMut { .. } => { generate_standard_indexing_impl( db, @@ -2614,7 +2681,12 @@ fn function_signature( } } Some( - TraitName::Clone | TraitName::CtorNew(..) | TraitName::Default | TraitName::From(..), + TraitName::Clone + | TraitName::CtorNew(..) + | TraitName::Default + | TraitName::From(..) + | TraitName::UnsafeCtorNew(..) + | TraitName::UnsafeFrom(..), ) => { move_self_from_out_param_to_return_value( db, @@ -2628,7 +2700,13 @@ fn function_signature( quoted_return_type = Some(quote! { Self }); // CtorNew and From group parameters into a tuple. - if let Some(TraitName::CtorNew(args_type) | TraitName::From(args_type)) = trait_name { + if let Some( + TraitName::CtorNew(args_type) + | TraitName::From(args_type) + | TraitName::UnsafeCtorNew(args_type) + | TraitName::UnsafeFrom(args_type), + ) = trait_name + { let args_type = if let Some(self_type) = self_type.as_ref() { format_tuple_except_singleton_replacing_by_self(db, args_type, Some(self_type)) } else { diff --git a/rs_bindings_from_cc/generate_bindings/generate_function_test.rs b/rs_bindings_from_cc/generate_bindings/generate_function_test.rs index ec35a5f23..6fa44e725 100644 --- a/rs_bindings_from_cc/generate_bindings/generate_function_test.rs +++ b/rs_bindings_from_cc/generate_bindings/generate_function_test.rs @@ -1464,8 +1464,8 @@ fn test_nonunpin_0_arg_constructor() -> Result<()> { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN14HasConstructorC1Ev(dest as *mut ::core::ffi::c_void); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN14HasConstructorC1Ev(__crubit_dest as *mut ::core::ffi::c_void); }) } } @@ -1498,8 +1498,8 @@ fn test_nonunpin_1_arg_constructor() -> Result<()> { fn ctor_new(args: ::ffi_11::c_uchar) -> Self::CtorType { let mut input = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN14HasConstructorC1Eh(dest as *mut ::core::ffi::c_void, input); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN14HasConstructorC1Eh(__crubit_dest as *mut ::core::ffi::c_void, input); }) } } @@ -1532,8 +1532,8 @@ fn test_nonunpin_2_arg_constructor() -> Result<()> { fn ctor_new(args: (::ffi_11::c_uchar, ::ffi_11::c_schar)) -> Self::CtorType { let (mut input1, mut input2) = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN14HasConstructorC1Eha(dest as *mut ::core::ffi::c_void, input1, input2); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN14HasConstructorC1Eha(__crubit_dest as *mut ::core::ffi::c_void, input1, input2); }) } } @@ -1584,8 +1584,8 @@ fn test_nonunpin_by_value_params() -> Result<()> { ) -> Self::CtorType { let (mut x, mut y, mut b) = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN14HasConstructorC1ERKiS_S_(dest as *mut ::core::ffi::c_void, x, y, b); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN14HasConstructorC1ERKiS_S_(__crubit_dest as *mut ::core::ffi::c_void, x, y, b); }) } } @@ -1612,8 +1612,8 @@ fn test_nonunpin_return() -> Result<()> { pub fn ReturnsByValue<'a, 'b>(x: &'a ::ffi_11::c_int, y: &'b ::ffi_11::c_int) -> impl ::ctor::Ctor + use<'a, 'b> { unsafe { - ::ctor::FnCtor::new(move |dest: *mut crate::Nontrivial| { - crate::detail::__rust_thunk___Z14ReturnsByValueRKiS0_(dest as *mut ::core::ffi::c_void, x, y); + ::ctor::FnCtor::new(move |__crubit_dest: *mut crate::Nontrivial| { + crate::detail::__rust_thunk___Z14ReturnsByValueRKiS0_(__crubit_dest as *mut ::core::ffi::c_void, x, y); }) } @@ -1650,8 +1650,8 @@ fn test_nonunpin_const_return() -> Result<()> { pub fn ReturnsByValue<'a, 'b>(x: &'a ::ffi_11::c_int, y: &'b ::ffi_11::c_int) -> impl ::ctor::Ctor + use<'a, 'b> { unsafe { - ::ctor::FnCtor::new(move |dest: *mut crate::Nontrivial| { - crate::detail::__rust_thunk___Z14ReturnsByValueRKiS0_(dest as *mut ::core::ffi::c_void, x, y); + ::ctor::FnCtor::new(move |__crubit_dest: *mut crate::Nontrivial| { + crate::detail::__rust_thunk___Z14ReturnsByValueRKiS0_(__crubit_dest as *mut ::core::ffi::c_void, x, y); }) } @@ -1835,9 +1835,9 @@ fn test_nonunpin_return_assign() -> Result<()> { fn assign<'a>(self: ::core::pin::Pin<&'a mut Self>, other: &'b Self) { unsafe { let _ = ::ctor::emplace!(::ctor::FnCtor::new( - move |dest: *mut Self| { + move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN10NontrivialaSERKS_( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, self, other ); @@ -2050,3 +2050,70 @@ fn test_simple_explicit_lifetime() -> Result<()> { assert_cc_not_matches!(rs_api_impl, quote! {__rust_thunk___Z3AddRi}); Ok(()) } + +#[gtest] +fn test_unsafe_constructor_unpin() -> Result<()> { + let ir = ir_from_cc( + r#" + struct StructWithUnsafeConstructor final { + explicit StructWithUnsafeConstructor(int* p) : ptr_field(p) {} + int* ptr_field; + };"#, + )?; + let BindingsTokens { rs_api, .. } = generate_bindings_tokens_for_test(ir)?; + assert_rs_matches!( + rs_api, + quote! { + impl ::ctor::UnsafeFrom<*mut ::ffi_11::c_int> for StructWithUnsafeConstructor { + #[inline(always)] + unsafe fn unsafe_from(args: *mut ::ffi_11::c_int) -> Self { + let mut p = args; + unsafe { + let mut __return = ::core::mem::MaybeUninit::::uninit(); + crate::detail::__rust_thunk___ZN27StructWithUnsafeConstructorC1EPi( + &raw mut __return as *mut ::core::ffi::c_void, + p + ); + __return.assume_init() + } + } + } + } + ); + Ok(()) +} + +#[gtest] +fn test_unsafe_constructor_nonunpin() -> Result<()> { + let ir = ir_from_cc( + r#" + struct NonUnpinStructWithUnsafeConstructor final { + explicit NonUnpinStructWithUnsafeConstructor(int* p) : ptr_field(p) {} + ~NonUnpinStructWithUnsafeConstructor(); // makes it non-Unpin + int* ptr_field; + };"#, + )?; + let BindingsTokens { rs_api, .. } = generate_bindings_tokens_for_test(ir)?; + assert_rs_matches!( + rs_api, + quote! { + impl ::ctor::UnsafeCtorNew<*mut ::ffi_11::c_int> for NonUnpinStructWithUnsafeConstructor { + type CtorType = ::ctor::Ctor![Self]; + type Error = ::ctor::Infallible; + #[inline(always)] + unsafe fn ctor_new(args: *mut ::ffi_11::c_int) -> Self::CtorType { + let mut p = args; + unsafe { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN35NonUnpinStructWithUnsafeConstructorC1EPi( + __crubit_dest as *mut ::core::ffi::c_void, + p + ); + }) + } + } + } + } + ); + Ok(()) +} diff --git a/rs_bindings_from_cc/generate_bindings/generate_function_thunk.rs b/rs_bindings_from_cc/generate_bindings/generate_function_thunk.rs index 141088a02..5045e3d50 100644 --- a/rs_bindings_from_cc/generate_bindings/generate_function_thunk.rs +++ b/rs_bindings_from_cc/generate_bindings/generate_function_thunk.rs @@ -489,7 +489,11 @@ pub fn generate_function_thunk_impl( }) } PassingConvention::LayoutCompatible | PassingConvention::Ctor => { - Ok(quote! { std::move(* #ident) }) + if rs_type_kind.is_c_abi_compatible_by_value() { + Ok(quote! { std::move( #ident) }) + } else { + Ok(quote! { std::move(* #ident) }) + } } PassingConvention::AbiCompatible | PassingConvention::OwnedPtr => { if rs_type_kind.is_primitive() || rs_type_kind.referent().is_some() { diff --git a/rs_bindings_from_cc/test/assume_lifetimes/struct_with_lifetimebound_rs_api.rs b/rs_bindings_from_cc/test/assume_lifetimes/struct_with_lifetimebound_rs_api.rs index 0060d37b7..e3e7d7152 100644 --- a/rs_bindings_from_cc/test/assume_lifetimes/struct_with_lifetimebound_rs_api.rs +++ b/rs_bindings_from_cc/test/assume_lifetimes/struct_with_lifetimebound_rs_api.rs @@ -172,9 +172,9 @@ impl ::ctor::CtorNew<()> for DropClassWithLifetimeboundMemberFunction { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN40DropClassWithLifetimeboundMemberFunctionC1Ev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } @@ -189,9 +189,9 @@ impl<'__param_0> ::ctor::CtorNew<&'__param_0 Self> for DropClassWithLifetimeboun fn ctor_new(args: &'__param_0 Self) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN40DropClassWithLifetimeboundMemberFunctionC1ERKS_( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, __param_0, ); }) @@ -279,9 +279,9 @@ impl<'__implicit> ::ctor::CtorNew<()> for DropClassWithLifetimeboundRefMemberFun fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN43DropClassWithLifetimeboundRefMemberFunctionC1Ev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } @@ -302,8 +302,8 @@ impl<'__implicit, '__param_0, '__param_0_0> ) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN43DropClassWithLifetimeboundRefMemberFunctionC1ERKS_(dest as*mut::core::ffi::c_void,__param_0); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN43DropClassWithLifetimeboundRefMemberFunctionC1ERKS_(__crubit_dest as*mut::core::ffi::c_void,__param_0); }) } } @@ -473,9 +473,9 @@ impl<'__param_0> ::ctor::CtorNew<&'__param_0 Self> for DropStructWithLifetimebou fn ctor_new(args: &'__param_0 Self) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN31DropStructWithLifetimeboundCtorC1ERKS_( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, __param_0, ); }) @@ -512,9 +512,9 @@ impl ::ctor::CtorNew for DropStructWithLifetimeboundCtor { fn ctor_new(args: crate::PlainStruct) -> Self::CtorType { let mut s = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN31DropStructWithLifetimeboundCtorC1E11PlainStruct( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, &mut s, ); }) @@ -568,9 +568,9 @@ impl<'__implicit, '__param_0, '__param_0_0> ) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN34DropStructWithLifetimeboundRefCtorC1ERKS_( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, __param_0, ); }) @@ -624,8 +624,10 @@ impl<'__implicit> ::ctor::CtorNew<&'__implicit crate::PlainStruct> let mut s = args; unsafe { ::ctor::FnCtor::new( - move |dest: *mut crate::DropStructWithLifetimeboundRefCtor<'__implicit>| { - crate::detail::__rust_thunk___ZN34DropStructWithLifetimeboundRefCtorC1ERK11PlainStruct(dest as*mut::core::ffi::c_void,s); + move |__crubit_dest: *mut crate::DropStructWithLifetimeboundRefCtor< + '__implicit, + >| { + crate::detail::__rust_thunk___ZN34DropStructWithLifetimeboundRefCtorC1ERK11PlainStruct(__crubit_dest as*mut::core::ffi::c_void,s); }, ) } @@ -689,9 +691,9 @@ impl<'__implicit, '__param_0, '__param_0_0> ) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN41DropStructWithRefCtorAndRefMemberFunctionC1ERKS_( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, __param_0, ); }) @@ -745,8 +747,10 @@ impl<'__implicit> ::ctor::CtorNew<&'__implicit crate::PlainStruct> let mut s = args; unsafe { ::ctor::FnCtor::new( - move |dest: *mut crate::DropStructWithRefCtorAndRefMemberFunction<'__implicit>| { - crate::detail::__rust_thunk___ZN41DropStructWithRefCtorAndRefMemberFunctionC1ERK11PlainStruct(dest as*mut::core::ffi::c_void,s); + move |__crubit_dest: *mut crate::DropStructWithRefCtorAndRefMemberFunction< + '__implicit, + >| { + crate::detail::__rust_thunk___ZN41DropStructWithRefCtorAndRefMemberFunctionC1ERK11PlainStruct(__crubit_dest as*mut::core::ffi::c_void,s); }, ) } @@ -815,9 +819,9 @@ impl<'__param_0> ::ctor::CtorNew<&'__param_0 Self> for DropStructWithCtorAndMemb fn ctor_new(args: &'__param_0 Self) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN35DropStructWithCtorAndMemberFunctionC1ERKS_( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, __param_0, ); }) @@ -854,8 +858,8 @@ impl ::ctor::CtorNew for DropStructWithCtorAndMemberFunction fn ctor_new(args: crate::PlainStruct) -> Self::CtorType { let mut s = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN35DropStructWithCtorAndMemberFunctionC1E11PlainStruct(dest as*mut::core::ffi::c_void,&mut s); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN35DropStructWithCtorAndMemberFunctionC1E11PlainStruct(__crubit_dest as*mut::core::ffi::c_void,&mut s); }) } } @@ -924,9 +928,9 @@ impl<'__param_0> ::ctor::CtorNew<&'__param_0 Self> for DropStructWithCtorAndRefM fn ctor_new(args: &'__param_0 Self) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN38DropStructWithCtorAndRefMemberFunctionC1ERKS_( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, __param_0, ); }) @@ -963,8 +967,8 @@ impl ::ctor::CtorNew for DropStructWithCtorAndRefMemberFunct fn ctor_new(args: crate::PlainStruct) -> Self::CtorType { let mut s = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN38DropStructWithCtorAndRefMemberFunctionC1E11PlainStruct(dest as*mut::core::ffi::c_void,&mut s); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN38DropStructWithCtorAndRefMemberFunctionC1E11PlainStruct(__crubit_dest as*mut::core::ffi::c_void,&mut s); }) } } @@ -1039,9 +1043,9 @@ impl<'__implicit, '__param_0, '__param_0_0> ) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN38DropStructWithRefCtorAndMemberFunctionC1ERKS_( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, __param_0, ); }) @@ -1095,8 +1099,10 @@ impl<'__implicit> ::ctor::CtorNew<&'__implicit crate::PlainStruct> let mut s = args; unsafe { ::ctor::FnCtor::new( - move |dest: *mut crate::DropStructWithRefCtorAndMemberFunction<'__implicit>| { - crate::detail::__rust_thunk___ZN38DropStructWithRefCtorAndMemberFunctionC1ERK11PlainStruct(dest as*mut::core::ffi::c_void,s); + move |__crubit_dest: *mut crate::DropStructWithRefCtorAndMemberFunction< + '__implicit, + >| { + crate::detail::__rust_thunk___ZN38DropStructWithRefCtorAndMemberFunctionC1ERK11PlainStruct(__crubit_dest as*mut::core::ffi::c_void,s); }, ) } diff --git a/rs_bindings_from_cc/test/golden/inheritance_rs_api.rs b/rs_bindings_from_cc/test/golden/inheritance_rs_api.rs index 312fa1bf2..23e628afe 100644 --- a/rs_bindings_from_cc/test/golden/inheritance_rs_api.rs +++ b/rs_bindings_from_cc/test/golden/inheritance_rs_api.rs @@ -223,9 +223,9 @@ impl ::ctor::CtorNew<()> for VirtualBase1 { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN12VirtualBase1C1Ev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } @@ -272,9 +272,9 @@ impl ::ctor::CtorNew<()> for VirtualBase2 { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN12VirtualBase2C1Ev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } @@ -321,9 +321,9 @@ impl ::ctor::CtorNew<()> for VirtualDerived { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN14VirtualDerivedC1Ev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } diff --git a/rs_bindings_from_cc/test/golden/no_elided_lifetimes_rs_api.rs b/rs_bindings_from_cc/test/golden/no_elided_lifetimes_rs_api.rs index 1768aac5d..9a02425e9 100644 --- a/rs_bindings_from_cc/test/golden/no_elided_lifetimes_rs_api.rs +++ b/rs_bindings_from_cc/test/golden/no_elided_lifetimes_rs_api.rs @@ -141,8 +141,8 @@ impl<'__unelided> ::ctor::CtorNew<&'__unelided Self> fn ctor_new(args: &'__unelided Self) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN44TriviallyCopyableButNontriviallyDestructibleC1ERKS_(dest as*mut::core::ffi::c_void,__param_0); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN44TriviallyCopyableButNontriviallyDestructibleC1ERKS_(__crubit_dest as*mut::core::ffi::c_void,__param_0); }) } } diff --git a/rs_bindings_from_cc/test/golden/no_unique_address_rs_api.rs b/rs_bindings_from_cc/test/golden/no_unique_address_rs_api.rs index 5ee49ed23..63e14ce1c 100644 --- a/rs_bindings_from_cc/test/golden/no_unique_address_rs_api.rs +++ b/rs_bindings_from_cc/test/golden/no_unique_address_rs_api.rs @@ -197,9 +197,9 @@ impl ::ctor::CtorNew<()> for FieldInTailPadding_InnerStruct { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN30FieldInTailPadding_InnerStructC1Ev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } @@ -285,9 +285,9 @@ impl ::ctor::CtorNew<(::ffi_11::c_int, ::ffi_11::c_char, ::ffi_11::c_char)> for fn ctor_new(args: (::ffi_11::c_int, ::ffi_11::c_char, ::ffi_11::c_char)) -> Self::CtorType { let (mut inner_int, mut inner_char, mut outer_char) = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN18FieldInTailPaddingC1Eicc( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, inner_int, inner_char, outer_char, diff --git a/rs_bindings_from_cc/test/golden/nontrivial_type_rs_api.rs b/rs_bindings_from_cc/test/golden/nontrivial_type_rs_api.rs index 374986fdc..8cd51fdb0 100644 --- a/rs_bindings_from_cc/test/golden/nontrivial_type_rs_api.rs +++ b/rs_bindings_from_cc/test/golden/nontrivial_type_rs_api.rs @@ -58,8 +58,10 @@ impl ::ctor::CtorNew<()> for Nontrivial { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN10NontrivialC1Ev(dest as *mut ::core::ffi::c_void); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN10NontrivialC1Ev( + __crubit_dest as *mut ::core::ffi::c_void, + ); }) } } @@ -72,9 +74,9 @@ impl ::ctor::CtorNew<::ffi_11::c_int> for Nontrivial { fn ctor_new(args: ::ffi_11::c_int) -> Self::CtorType { let mut field = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN10NontrivialC1Ei( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, field, ); }) @@ -98,9 +100,9 @@ impl ::ctor::CtorNew<(::ffi_11::c_int, ::ffi_11::c_int)> for Nontrivial { fn ctor_new(args: (::ffi_11::c_int, ::ffi_11::c_int)) -> Self::CtorType { let (mut field, mut unused) = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN10NontrivialC1Eii( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, field, unused, ); @@ -137,9 +139,9 @@ impl ::ctor::Assign for Nontrivial { #[inline(always)] fn assign<'a>(self: ::core::pin::Pin<&'a mut Self>, __param_0: f32) { unsafe { - let _ = ::ctor::emplace!(::ctor::FnCtor::new(move |dest: *mut Self| { + let _ = ::ctor::emplace!(::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN10NontrivialaSEf( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, self, __param_0, ); @@ -232,9 +234,9 @@ impl ::ctor::CtorNew<()> for NontrivialInline { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN16NontrivialInlineC1Ev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } @@ -248,9 +250,9 @@ impl ::ctor::CtorNew<::ffi_11::c_int> for NontrivialInline { fn ctor_new(args: ::ffi_11::c_int) -> Self::CtorType { let mut field = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN16NontrivialInlineC1Ei( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, field, ); }) @@ -274,9 +276,9 @@ impl ::ctor::CtorNew<(::ffi_11::c_int, ::ffi_11::c_int)> for NontrivialInline { fn ctor_new(args: (::ffi_11::c_int, ::ffi_11::c_int)) -> Self::CtorType { let (mut field, mut unused) = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN16NontrivialInlineC1Eii( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, field, unused, ); @@ -350,9 +352,9 @@ impl ::ctor::CtorNew<()> for NontrivialMembers { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN17NontrivialMembersC1Ev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } @@ -508,9 +510,9 @@ pub fn TakesByValue( nontrivial: ::ctor::Ctor![crate::Nontrivial], ) -> ::ctor::Ctor![crate::Nontrivial] { unsafe { - ::ctor::FnCtor::new(move |dest: *mut crate::Nontrivial| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut crate::Nontrivial| { crate::detail::__rust_thunk___Z12TakesByValue10Nontrivial( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ::core::pin::Pin::into_inner_unchecked(::ctor::emplace!(nontrivial)), ); }) @@ -522,9 +524,9 @@ pub fn TakesByValueInline( nontrivial: ::ctor::Ctor![crate::NontrivialInline], ) -> ::ctor::Ctor![crate::NontrivialInline] { unsafe { - ::ctor::FnCtor::new(move |dest: *mut crate::NontrivialInline| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut crate::NontrivialInline| { crate::detail::__rust_thunk___Z18TakesByValueInline16NontrivialInline( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ::core::pin::Pin::into_inner_unchecked(::ctor::emplace!(nontrivial)), ); }) @@ -686,8 +688,10 @@ impl ::ctor::CtorNew<()> for Nonmovable { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN10NonmovableC1Ev(dest as *mut ::core::ffi::c_void); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN10NonmovableC1Ev( + __crubit_dest as *mut ::core::ffi::c_void, + ); }) } } @@ -726,9 +730,9 @@ where #[inline(always)] pub fn ReturnsNonmovableByValue() -> ::ctor::Ctor![crate::Nonmovable] { unsafe { - ::ctor::FnCtor::new(move |dest: *mut crate::Nonmovable| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut crate::Nonmovable| { crate::detail::__rust_thunk___Z24ReturnsNonmovableByValuev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } diff --git a/rs_bindings_from_cc/test/golden/operators_rs_api.rs b/rs_bindings_from_cc/test/golden/operators_rs_api.rs index 8c6edf96d..2926f6a8e 100644 --- a/rs_bindings_from_cc/test/golden/operators_rs_api.rs +++ b/rs_bindings_from_cc/test/golden/operators_rs_api.rs @@ -552,9 +552,9 @@ impl ::ctor::CtorNew<()> for AddableConstMemberNonunpin { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN26AddableConstMemberNonunpinC1Ev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } diff --git a/rs_bindings_from_cc/test/golden/polymorphic_rs_api.rs b/rs_bindings_from_cc/test/golden/polymorphic_rs_api.rs index dc487e6a9..4d80fb4a3 100644 --- a/rs_bindings_from_cc/test/golden/polymorphic_rs_api.rs +++ b/rs_bindings_from_cc/test/golden/polymorphic_rs_api.rs @@ -34,9 +34,9 @@ impl ::ctor::CtorNew<()> for PolymorphicBase { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN15PolymorphicBaseC1Ev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } @@ -95,9 +95,9 @@ impl ::ctor::CtorNew<()> for PolymorphicBase2 { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN16PolymorphicBase2C1Ev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } @@ -157,9 +157,9 @@ impl ::ctor::CtorNew<()> for PolymorphicDerived { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN18PolymorphicDerivedC1Ev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } diff --git a/rs_bindings_from_cc/test/golden/unions_rs_api.rs b/rs_bindings_from_cc/test/golden/unions_rs_api.rs index 8ffc88bb7..508a338fb 100644 --- a/rs_bindings_from_cc/test/golden/unions_rs_api.rs +++ b/rs_bindings_from_cc/test/golden/unions_rs_api.rs @@ -83,8 +83,10 @@ impl ::ctor::CtorNew<()> for Nontrivial { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN10NontrivialC1Ev(dest as *mut ::core::ffi::c_void); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN10NontrivialC1Ev( + __crubit_dest as *mut ::core::ffi::c_void, + ); }) } } diff --git a/rs_bindings_from_cc/test/golden/user_of_base_class_rs_api.rs b/rs_bindings_from_cc/test/golden/user_of_base_class_rs_api.rs index de618eac0..65b642fa8 100644 --- a/rs_bindings_from_cc/test/golden/user_of_base_class_rs_api.rs +++ b/rs_bindings_from_cc/test/golden/user_of_base_class_rs_api.rs @@ -40,8 +40,10 @@ impl ::ctor::CtorNew<()> for Derived2 { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN8Derived2C1Ev(dest as *mut ::core::ffi::c_void); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN8Derived2C1Ev( + __crubit_dest as *mut ::core::ffi::c_void, + ); }) } } @@ -87,9 +89,9 @@ impl ::ctor::CtorNew<()> for VirtualDerived2 { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN15VirtualDerived2C1Ev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } diff --git a/rs_bindings_from_cc/test/operators/operators_index_rs_api.rs b/rs_bindings_from_cc/test/operators/operators_index_rs_api.rs index 7bf82abd5..0b6d76f9e 100644 --- a/rs_bindings_from_cc/test/operators/operators_index_rs_api.rs +++ b/rs_bindings_from_cc/test/operators/operators_index_rs_api.rs @@ -67,9 +67,9 @@ pub mod crubit { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN6crubit4test12ItemNonUnpinC1Ev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } @@ -85,9 +85,9 @@ pub mod crubit { fn ctor_new(args: &'__unelided Self) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN6crubit4test12ItemNonUnpinC1ERKS1_( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, __param_0, ); }) @@ -233,8 +233,8 @@ pub mod crubit { fn ctor_new(args: &'__unelided Self) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN6crubit4test26ContainerUnpinItemNonUnpinC1ERKS1_(dest as*mut::core::ffi::c_void,__param_0); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN6crubit4test26ContainerUnpinItemNonUnpinC1ERKS1_(__crubit_dest as*mut::core::ffi::c_void,__param_0); }) } } @@ -261,8 +261,8 @@ pub mod crubit { fn ctor_new(args: ::ctor::RvalueReference<'__unelided, Self>) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN6crubit4test26ContainerUnpinItemNonUnpinC1EOS1_(dest as*mut::core::ffi::c_void,__param_0); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN6crubit4test26ContainerUnpinItemNonUnpinC1EOS1_(__crubit_dest as*mut::core::ffi::c_void,__param_0); }) } } @@ -325,17 +325,40 @@ pub mod crubit { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN6crubit4test26ContainerUnpinItemNonUnpinC1Ev(dest as*mut::core::ffi::c_void); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN6crubit4test26ContainerUnpinItemNonUnpinC1Ev(__crubit_dest as*mut::core::ffi::c_void); }) } } } - // Generated from: rs_bindings_from_cc/test/operators/operators_index.h;l=35 - // error: constructor `crubit::test::ContainerUnpinItemNonUnpin::ContainerUnpinItemNonUnpin` could not be bound - // Constructors cannot be `unsafe`, but this constructor accepts: - // `items`: raw pointer + /// Generated from: rs_bindings_from_cc/test/operators/operators_index.h;l=35 + impl ::ctor::UnsafeCtorNew<*mut crate::crubit::test::ItemNonUnpin> for ContainerUnpinItemNonUnpin { + type CtorType = ::ctor::Ctor![Self]; + type Error = ::ctor::Infallible; + #[inline(always)] + unsafe fn ctor_new(args: *mut crate::crubit::test::ItemNonUnpin) -> Self::CtorType { + let mut items = args; + unsafe { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN6crubit4test26ContainerUnpinItemNonUnpinC1EPNS0_12ItemNonUnpinE(__crubit_dest as*mut::core::ffi::c_void,items); + }) + } + } + } + impl ::ctor::UnsafeCtorNew<(*mut crate::crubit::test::ItemNonUnpin,)> + for ContainerUnpinItemNonUnpin + { + type CtorType = ::ctor::Ctor![Self]; + type Error = ::ctor::Infallible; + #[inline(always)] + unsafe fn ctor_new(args: (*mut crate::crubit::test::ItemNonUnpin,)) -> Self::CtorType { + let (arg,) = args; + >::ctor_new( + arg, + ) + } + } /// Generated from: rs_bindings_from_cc/test/operators/operators_index.h;l=37 impl ::operator::CcIndex<::ffi_11::c_uint> for ContainerUnpinItemNonUnpin { @@ -401,8 +424,8 @@ pub mod crubit { fn ctor_new(args: &'__unelided Self) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN6crubit4test26ContainerNonUnpinItemUnpinC1ERKS1_(dest as*mut::core::ffi::c_void,__param_0); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN6crubit4test26ContainerNonUnpinItemUnpinC1ERKS1_(__crubit_dest as*mut::core::ffi::c_void,__param_0); }) } } @@ -436,8 +459,8 @@ pub mod crubit { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN6crubit4test26ContainerNonUnpinItemUnpinC1Ev(dest as*mut::core::ffi::c_void); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN6crubit4test26ContainerNonUnpinItemUnpinC1Ev(__crubit_dest as*mut::core::ffi::c_void); }) } } @@ -527,8 +550,8 @@ pub mod crubit { fn ctor_new(args: &'__unelided Self) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN6crubit4test29ContainerNonUnpinItemNonUnpinC1ERKS1_(dest as*mut::core::ffi::c_void,__param_0); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN6crubit4test29ContainerNonUnpinItemNonUnpinC1ERKS1_(__crubit_dest as*mut::core::ffi::c_void,__param_0); }) } } @@ -562,8 +585,8 @@ pub mod crubit { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN6crubit4test29ContainerNonUnpinItemNonUnpinC1Ev(dest as*mut::core::ffi::c_void); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN6crubit4test29ContainerNonUnpinItemNonUnpinC1Ev(__crubit_dest as*mut::core::ffi::c_void); }) } } @@ -835,6 +858,10 @@ mod detail { pub(crate) unsafe fn __rust_thunk___ZN6crubit4test26ContainerUnpinItemNonUnpinC1Ev( __this: *mut ::core::ffi::c_void, ); + pub(crate) unsafe fn __rust_thunk___ZN6crubit4test26ContainerUnpinItemNonUnpinC1EPNS0_12ItemNonUnpinE( + __this: *mut ::core::ffi::c_void, + items: *mut crate::crubit::test::ItemNonUnpin, + ); pub(crate) unsafe fn __rust_thunk___ZNK6crubit4test26ContainerUnpinItemNonUnpinixEj< '__return_lifetime, >( diff --git a/rs_bindings_from_cc/test/operators/operators_index_rs_api_impl.cc b/rs_bindings_from_cc/test/operators/operators_index_rs_api_impl.cc index 1c8b90067..904d24a8e 100644 --- a/rs_bindings_from_cc/test/operators/operators_index_rs_api_impl.cc +++ b/rs_bindings_from_cc/test/operators/operators_index_rs_api_impl.cc @@ -124,6 +124,13 @@ extern "C" void __rust_thunk___ZN6crubit4test26ContainerUnpinItemNonUnpinC1Ev( crubit::construct_at(__this); } +extern "C" void +__rust_thunk___ZN6crubit4test26ContainerUnpinItemNonUnpinC1EPNS0_12ItemNonUnpinE( + class crubit::test::ContainerUnpinItemNonUnpin* __this, + struct crubit::test::ItemNonUnpin* items) { + crubit::construct_at(__this, items); +} + extern "C" struct crubit::test::ItemNonUnpin const* __rust_thunk___ZNK6crubit4test26ContainerUnpinItemNonUnpinixEj( class crubit::test::ContainerUnpinItemNonUnpin const* __this, diff --git a/rs_bindings_from_cc/test/references/references_api_impl.cc b/rs_bindings_from_cc/test/references/references_api_impl.cc index bad5879b3..109fdd501 100644 --- a/rs_bindings_from_cc/test/references/references_api_impl.cc +++ b/rs_bindings_from_cc/test/references/references_api_impl.cc @@ -22,9 +22,19 @@ static_assert(sizeof(class TypeWithPtrConstructor) == 1); static_assert(alignof(class TypeWithPtrConstructor) == 1); +extern "C" void __rust_thunk___ZN22TypeWithPtrConstructorC1EPi( + class TypeWithPtrConstructor* __this, int* ptr) { + crubit::construct_at(__this, ptr); +} + static_assert(sizeof(class TypeWithNonNullPtrConstructor) == 1); static_assert(alignof(class TypeWithNonNullPtrConstructor) == 1); +extern "C" void __rust_thunk___ZN29TypeWithNonNullPtrConstructorC1EPi( + class TypeWithNonNullPtrConstructor* __this, int* ptr) { + crubit::construct_at(__this, ptr); +} + static_assert(sizeof(class TypeWithReferenceConstructor) == 1); static_assert(alignof(class TypeWithReferenceConstructor) == 1); diff --git a/rs_bindings_from_cc/test/references/references_rs_api.rs b/rs_bindings_from_cc/test/references/references_rs_api.rs index ac869942b..4cfa5f35b 100644 --- a/rs_bindings_from_cc/test/references/references_rs_api.rs +++ b/rs_bindings_from_cc/test/references/references_rs_api.rs @@ -29,22 +29,27 @@ unsafe impl ::cxx::ExternType for TypeWithPtrConstructor { type Kind = ::cxx::kind::Trivial; } -#[diagnostic::on_unimplemented( - message = "binding generation for function failed\nConstructors cannot be `unsafe`, but this constructor accepts:\n `ptr`: raw pointer" -)] -pub trait BindingFailedFor_ZN22TypeWithPtrConstructorC1EPi {} /// Generated from: rs_bindings_from_cc/test/references/references.h;l=10 -impl From<*mut ::ffi_11::c_int> for TypeWithPtrConstructor -where - for<'error> &'error (): BindingFailedFor_ZN22TypeWithPtrConstructorC1EPi, -{ +impl ::ctor::UnsafeFrom<*mut ::ffi_11::c_int> for TypeWithPtrConstructor { #[inline(always)] - fn from(args: *mut ::ffi_11::c_int) -> Self { - #![allow(unused_variables)] - unreachable!( - "This impl can never be instantiated. \ - If this message appears at runtime, please report a crubit.rs-bug." - ) + unsafe fn unsafe_from(args: *mut ::ffi_11::c_int) -> Self { + let mut ptr = args; + unsafe { + let mut __return = ::core::mem::MaybeUninit::::uninit(); + crate::detail::__rust_thunk___ZN22TypeWithPtrConstructorC1EPi( + &raw mut __return as *mut ::core::ffi::c_void, + ptr, + ); + __return.assume_init() + } + } +} +impl ::ctor::UnsafeCtorNew<*mut ::ffi_11::c_int> for TypeWithPtrConstructor { + type CtorType = Self; + type Error = ::ctor::Infallible; + #[inline(always)] + unsafe fn ctor_new(args: *mut ::ffi_11::c_int) -> Self::CtorType { + >::unsafe_from(args) } } @@ -62,22 +67,27 @@ unsafe impl ::cxx::ExternType for TypeWithNonNullPtrConstructor { type Kind = ::cxx::kind::Trivial; } -#[diagnostic::on_unimplemented( - message = "binding generation for function failed\nConstructors cannot be `unsafe`, but this constructor accepts:\n `ptr`: raw pointer" -)] -pub trait BindingFailedFor_ZN29TypeWithNonNullPtrConstructorC1EPi {} /// Generated from: rs_bindings_from_cc/test/references/references.h;l=15 -impl From<*mut ::ffi_11::c_int> for TypeWithNonNullPtrConstructor -where - for<'error> &'error (): BindingFailedFor_ZN29TypeWithNonNullPtrConstructorC1EPi, -{ +impl ::ctor::UnsafeFrom<*mut ::ffi_11::c_int> for TypeWithNonNullPtrConstructor { + #[inline(always)] + unsafe fn unsafe_from(args: *mut ::ffi_11::c_int) -> Self { + let mut ptr = args; + unsafe { + let mut __return = ::core::mem::MaybeUninit::::uninit(); + crate::detail::__rust_thunk___ZN29TypeWithNonNullPtrConstructorC1EPi( + &raw mut __return as *mut ::core::ffi::c_void, + ptr, + ); + __return.assume_init() + } + } +} +impl ::ctor::UnsafeCtorNew<*mut ::ffi_11::c_int> for TypeWithNonNullPtrConstructor { + type CtorType = Self; + type Error = ::ctor::Infallible; #[inline(always)] - fn from(args: *mut ::ffi_11::c_int) -> Self { - #![allow(unused_variables)] - unreachable!( - "This impl can never be instantiated. \ - If this message appears at runtime, please report a crubit.rs-bug." - ) + unsafe fn ctor_new(args: *mut ::ffi_11::c_int) -> Self::CtorType { + >::unsafe_from(args) } } @@ -123,6 +133,14 @@ mod detail { #[allow(unused_imports)] use super::*; unsafe extern "C" { + pub(crate) unsafe fn __rust_thunk___ZN22TypeWithPtrConstructorC1EPi( + __this: *mut ::core::ffi::c_void, + ptr: *mut ::ffi_11::c_int, + ); + pub(crate) unsafe fn __rust_thunk___ZN29TypeWithNonNullPtrConstructorC1EPi( + __this: *mut ::core::ffi::c_void, + ptr: *mut ::ffi_11::c_int, + ); pub(crate) unsafe fn __rust_thunk___ZN28TypeWithReferenceConstructorC1ERi( __this: *mut ::core::ffi::c_void, r#ref: &mut ::ffi_11::c_int, diff --git a/rs_bindings_from_cc/test/struct/constructors/constructors.h b/rs_bindings_from_cc/test/struct/constructors/constructors.h index 20c89204a..3492abc2a 100644 --- a/rs_bindings_from_cc/test/struct/constructors/constructors.h +++ b/rs_bindings_from_cc/test/struct/constructors/constructors.h @@ -106,4 +106,9 @@ struct NonTrivialStructWithConstructors final { int int_field; }; +struct StructWithUnsafeConstructor final { + explicit StructWithUnsafeConstructor(int* p) : ptr_field(p) {} + int* ptr_field; +}; + #endif // CRUBIT_RS_BINDINGS_FROM_CC_TEST_STRUCT_CONSTRUCTORS_CONSTRUCTORS_H_ diff --git a/rs_bindings_from_cc/test/struct/constructors/constructors_api_impl.cc b/rs_bindings_from_cc/test/struct/constructors/constructors_api_impl.cc index 1d8ff736f..c260ea11d 100644 --- a/rs_bindings_from_cc/test/struct/constructors/constructors_api_impl.cc +++ b/rs_bindings_from_cc/test/struct/constructors/constructors_api_impl.cc @@ -183,4 +183,14 @@ __rust_thunk___ZN32NonTrivialStructWithConstructorsaSERKS_( return std::addressof(__this->operator=(*__param_0)); } +static_assert(CRUBIT_SIZEOF(struct ::StructWithUnsafeConstructor) == 8); +static_assert(alignof(struct ::StructWithUnsafeConstructor) == 8); +static_assert(CRUBIT_OFFSET_OF(ptr_field, + struct ::StructWithUnsafeConstructor) == 0); + +extern "C" void __rust_thunk___ZN27StructWithUnsafeConstructorC1EPi( + struct ::StructWithUnsafeConstructor* __this, int* p) { + crubit::construct_at(__this, p); +} + #pragma clang diagnostic pop diff --git a/rs_bindings_from_cc/test/struct/constructors/constructors_rs_api.rs b/rs_bindings_from_cc/test/struct/constructors/constructors_rs_api.rs index 2d0a15398..9744ec39e 100644 --- a/rs_bindings_from_cc/test/struct/constructors/constructors_rs_api.rs +++ b/rs_bindings_from_cc/test/struct/constructors/constructors_rs_api.rs @@ -559,9 +559,9 @@ impl<'__param_0> ::ctor::CtorNew<&'__param_0 Self> for NonTrivialStructWithConst fn ctor_new(args: &'__param_0 Self) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN32NonTrivialStructWithConstructorsC1ERKS_( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, __param_0, ); }) @@ -598,9 +598,9 @@ impl ::ctor::CtorNew<()> for NonTrivialStructWithConstructors { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN32NonTrivialStructWithConstructorsC1Ev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } @@ -615,9 +615,9 @@ impl ::ctor::CtorNew<::ffi_11::c_int> for NonTrivialStructWithConstructors { fn ctor_new(args: ::ffi_11::c_int) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN32NonTrivialStructWithConstructorsC1Ei( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, __param_0, ); }) @@ -644,6 +644,55 @@ impl ::ctor::PinnedDrop for NonTrivialStructWithConstructors { } } +/// # Safety +/// +/// To call a function that accepts this type, you must uphold these requirements: +/// * Document why the following public unsafe fields of this type cannot be misused by callee: +/// * `ptr_field`: raw pointer +/// +/// Generated from: rs_bindings_from_cc/test/struct/constructors/constructors.h;l=109 +#[derive(Clone, Copy, ::ctor::MoveAndAssignViaCopy)] +#[repr(C)] +///CRUBIT_ANNOTATE: cpp_type=:: StructWithUnsafeConstructor +pub struct StructWithUnsafeConstructor { + __non_field_data: [::core::mem::MaybeUninit; 0], + pub ptr_field: *mut ::ffi_11::c_int, +} +impl !Send for StructWithUnsafeConstructor {} +impl !Sync for StructWithUnsafeConstructor {} +unsafe impl ::cxx::ExternType for StructWithUnsafeConstructor { + type Id = ::cxx::type_id!(":: StructWithUnsafeConstructor"); + type Kind = ::cxx::kind::Trivial; +} +forward_declare::unsafe_define!( + forward_declare::symbol!(":: StructWithUnsafeConstructor"), + crate::StructWithUnsafeConstructor +); + +/// Generated from: rs_bindings_from_cc/test/struct/constructors/constructors.h;l=110 +impl ::ctor::UnsafeFrom<*mut ::ffi_11::c_int> for StructWithUnsafeConstructor { + #[inline(always)] + unsafe fn unsafe_from(args: *mut ::ffi_11::c_int) -> Self { + let mut p = args; + unsafe { + let mut __return = ::core::mem::MaybeUninit::::uninit(); + crate::detail::__rust_thunk___ZN27StructWithUnsafeConstructorC1EPi( + &raw mut __return as *mut ::core::ffi::c_void, + p, + ); + __return.assume_init() + } + } +} +impl ::ctor::UnsafeCtorNew<*mut ::ffi_11::c_int> for StructWithUnsafeConstructor { + type CtorType = Self; + type Error = ::ctor::Infallible; + #[inline(always)] + unsafe fn ctor_new(args: *mut ::ffi_11::c_int) -> Self::CtorType { + >::unsafe_from(args) + } +} + mod detail { #[allow(unused_imports)] use super::*; @@ -759,6 +808,10 @@ mod detail { pub(crate) unsafe fn __rust_thunk___ZN32NonTrivialStructWithConstructorsD1Ev<'__this>( __this: ::core::pin::Pin<&'__this mut crate::NonTrivialStructWithConstructors>, ); + pub(crate) unsafe fn __rust_thunk___ZN27StructWithUnsafeConstructorC1EPi( + __this: *mut ::core::ffi::c_void, + p: *mut ::ffi_11::c_int, + ); } } @@ -832,4 +885,9 @@ const _: () = { static_assertions::assert_not_impl_any!(crate::NonTrivialStructWithConstructors: Copy); assert!(::core::mem::offset_of!(crate::NonTrivialStructWithConstructors, int_field) == 0); static_assertions::assert_impl_all!(::ffi_11::c_int: Copy); + assert!(::core::mem::size_of::() == 8); + assert!(::core::mem::align_of::() == 8); + static_assertions::assert_impl_all!(crate::StructWithUnsafeConstructor: Copy,Clone); + static_assertions::assert_not_impl_any!(crate::StructWithUnsafeConstructor: Drop); + assert!(::core::mem::offset_of!(crate::StructWithUnsafeConstructor, ptr_field) == 0); }; diff --git a/rs_bindings_from_cc/test/struct/constructors/test.rs b/rs_bindings_from_cc/test/struct/constructors/test.rs index 72c28fd35..9ac92961d 100644 --- a/rs_bindings_from_cc/test/struct/constructors/test.rs +++ b/rs_bindings_from_cc/test/struct/constructors/test.rs @@ -7,10 +7,11 @@ use constructors::{ StructWithExplicitConversionConstructor, StructWithExplicitlyDefaultedConstructors, StructWithImplicitConversionConstructor, StructWithImplicitConversionFromReference, StructWithInlineConstructors, StructWithMultipleConstructors, StructWithPrivateConstructors, - StructWithUserProvidedConstructors, + StructWithUnsafeConstructor, StructWithUserProvidedConstructors, }; use ctor::emplace; use ctor::CtorNew as _; +use ctor::UnsafeFrom as _; use googletest::gtest; use static_assertions::{assert_impl_all, assert_not_impl_any}; @@ -132,6 +133,17 @@ fn test_nontrivial_struct() { assert_eq!(s_clone.int_field, 123); } +#[gtest] +fn test_unsafe_constructor() { + let mut x = 42; + let p: *mut i32 = &mut x; + // SAFETY: We are passing a valid pointer. + let s = unsafe { StructWithUnsafeConstructor::unsafe_from(p) }; + unsafe { + assert_eq!(*s.ptr_field, 42); + } +} + // Ideally, this test would work. // // // TODO(b/331685208): make this test compile and pass. diff --git a/rs_bindings_from_cc/test/struct/default_member_functions/default_member_functions_rs_api.rs b/rs_bindings_from_cc/test/struct/default_member_functions/default_member_functions_rs_api.rs index ac89ff535..92483873f 100644 --- a/rs_bindings_from_cc/test/struct/default_member_functions/default_member_functions_rs_api.rs +++ b/rs_bindings_from_cc/test/struct/default_member_functions/default_member_functions_rs_api.rs @@ -37,8 +37,10 @@ impl ::ctor::CtorNew<()> for Uncopyable { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN10UncopyableC1Ev(dest as *mut ::core::ffi::c_void); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN10UncopyableC1Ev( + __crubit_dest as *mut ::core::ffi::c_void, + ); }) } } @@ -81,9 +83,9 @@ impl ::ctor::CtorNew<()> for UncopyableDespiteDecl { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN21UncopyableDespiteDeclC1Ev( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, ); }) } diff --git a/rs_bindings_from_cc/test/struct/inheritance/inherited_methods_rs_api.rs b/rs_bindings_from_cc/test/struct/inheritance/inherited_methods_rs_api.rs index f799c0247..e143cff89 100644 --- a/rs_bindings_from_cc/test/struct/inheritance/inherited_methods_rs_api.rs +++ b/rs_bindings_from_cc/test/struct/inheritance/inherited_methods_rs_api.rs @@ -38,8 +38,10 @@ impl ::ctor::CtorNew<()> for Nonmovable { fn ctor_new(args: ()) -> Self::CtorType { let () = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { - crate::detail::__rust_thunk___ZN10NonmovableC1Ev(dest as *mut ::core::ffi::c_void); + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { + crate::detail::__rust_thunk___ZN10NonmovableC1Ev( + __crubit_dest as *mut ::core::ffi::c_void, + ); }) } } diff --git a/rs_bindings_from_cc/test/types_only/types_only_rs_api.rs b/rs_bindings_from_cc/test/types_only/types_only_rs_api.rs index 0741f440d..94f5a5173 100644 --- a/rs_bindings_from_cc/test/types_only/types_only_rs_api.rs +++ b/rs_bindings_from_cc/test/types_only/types_only_rs_api.rs @@ -72,9 +72,9 @@ impl ::ctor::CtorNew<::ffi_11::c_int> for Cloneable { fn ctor_new(args: ::ffi_11::c_int) -> Self::CtorType { let mut field = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN9CloneableC1Ei( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, field, ); }) @@ -99,9 +99,9 @@ impl<'__unelided> ::ctor::CtorNew<&'__unelided Self> for Cloneable { fn ctor_new(args: &'__unelided Self) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN9CloneableC1ERKS_( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, __param_0, ); }) @@ -126,9 +126,9 @@ impl<'__unelided> ::ctor::CtorNew<::ctor::RvalueReference<'__unelided, Self>> fo fn ctor_new(args: ::ctor::RvalueReference<'__unelided, Self>) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN9CloneableC1EOS_( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, __param_0, ); }) @@ -198,9 +198,9 @@ impl ::ctor::CtorNew<::ffi_11::c_int> for Movable { fn ctor_new(args: ::ffi_11::c_int) -> Self::CtorType { let mut field = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN7MovableC1Ei( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, field, ); }) @@ -225,9 +225,9 @@ impl<'__unelided> ::ctor::CtorNew<::ctor::RvalueReference<'__unelided, Self>> fo fn ctor_new(args: ::ctor::RvalueReference<'__unelided, Self>) -> Self::CtorType { let mut other = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN7MovableC1EOS_( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, other, ); }) diff --git a/rs_bindings_from_cc/test/wrapper/impl_ctor/impl_ctor_rs_api.rs b/rs_bindings_from_cc/test/wrapper/impl_ctor/impl_ctor_rs_api.rs index 9290dae3e..f98efc3cf 100644 --- a/rs_bindings_from_cc/test/wrapper/impl_ctor/impl_ctor_rs_api.rs +++ b/rs_bindings_from_cc/test/wrapper/impl_ctor/impl_ctor_rs_api.rs @@ -39,9 +39,9 @@ impl ::ctor::CtorNew<::ffi_11::c_int> for Nontrivial { fn ctor_new(args: ::ffi_11::c_int) -> Self::CtorType { let mut x = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN10NontrivialC1Ei( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, x, ); }) @@ -66,9 +66,9 @@ impl<'__unelided> ::ctor::CtorNew<::ctor::RvalueReference<'__unelided, Self>> fo fn ctor_new(args: ::ctor::RvalueReference<'__unelided, Self>) -> Self::CtorType { let mut __param_0 = args; unsafe { - ::ctor::FnCtor::new(move |dest: *mut Self| { + ::ctor::FnCtor::new(move |__crubit_dest: *mut Self| { crate::detail::__rust_thunk___ZN10NontrivialC1EOS_( - dest as *mut ::core::ffi::c_void, + __crubit_dest as *mut ::core::ffi::c_void, __param_0, ); }) @@ -107,8 +107,8 @@ impl ::ctor::PinnedDrop for Nontrivial { #[inline(always)] pub fn Create() -> ::ctor::Ctor![crate::Nontrivial] { unsafe { - ::ctor::FnCtor::new(move |dest: *mut crate::Nontrivial| { - crate::detail::__rust_thunk___Z6Createv(dest as *mut ::core::ffi::c_void); + ::ctor::FnCtor::new(move |__crubit_dest: *mut crate::Nontrivial| { + crate::detail::__rust_thunk___Z6Createv(__crubit_dest as *mut ::core::ffi::c_void); }) } } diff --git a/support/ctor.rs b/support/ctor.rs index 5ec218d93..a250aec67 100644 --- a/support/ctor.rs +++ b/support/ctor.rs @@ -1725,6 +1725,19 @@ pub trait UnpinAssign { fn unpin_assign(&mut self, src: From); } +/// A conversion trait that is considered unsafe. +/// +/// This is used for `Unpin` types when the conversion involves unsafe operations +/// or types. +pub trait UnsafeFrom { + /// Performs the conversion. + /// + /// # Safety + /// + /// The caller must ensure that the conversion is safe. + unsafe fn unsafe_from(src: From) -> Self; +} + // ======================= // Constructor overloading // ======================= @@ -1749,6 +1762,25 @@ pub trait CtorNew { fn ctor_new(args: ConstructorArgs) -> Self::CtorType; } +/// Overloaded constructor trait for constructors that are considered unsafe. +/// +/// This is used when the constructor accepts arguments that are unsafe to use, +/// or when the constructor itself is marked unsafe in C++. +/// +/// `T : UnsafeCtorNew<(A, B, C)>` is roughly equivalent to the C++ "T has an +/// unsafe constructor taking arguments of type A, B, and C". +pub trait UnsafeCtorNew { + type CtorType: Ctor; + type Error; + + /// Creates a new constructor. + /// + /// # Safety + /// + /// The caller must ensure that the arguments are safe to use for construction. + unsafe fn ctor_new(args: ConstructorArgs) -> Self::CtorType; +} + // ==== // Misc // ====