diff --git a/docs/cpp/non_rust_movable.md b/docs/cpp/non_rust_movable.md index 682837ec7..78f18a8c7 100644 --- a/docs/cpp/non_rust_movable.md +++ b/docs/cpp/non_rust_movable.md @@ -23,11 +23,12 @@ support/ctor.rs `Ctor` is a trait for implementing **lazily evaluated values**. These values are constructed in-place, in a C++-compatible way, and -pinned. +pinned. It is typically used as an `impl Ctor`, which is most +easily spelled as `Ctor![T]` or `Ctor![T, Error=...]`. -However, `Ctor` is not a lazily-initialized value itself. It is a value -initialization procedure, which returns `T` upon success and `E` upon failure. -So a `Ctor` creates a value upon request, which is why we describe it as lazy. +`Ctor` is not a lazily-initialized value itself. It is a value initialization +procedure, which returns `T` upon success and `E` upon failure. So a `Ctor` +creates a value upon request, which is why we describe it as lazy. Since exceptions are disabled at Google, we currently only work with `Error=Infallible`, and for exposition will omit the error type. @@ -36,8 +37,9 @@ Functions accepting and returning a non-Rust movable value in C++ will accept and return an `impl Ctor` in Rust, as so: ```rust -pub fn accepts_value(x: impl Ctor) {...} -pub fn returns() -> impl Ctor {...} +pub fn accepts_value(x: Ctor![CppType]) {...} +// equivalent to x: impl Ctor +pub fn returns() -> Ctor![CppType] {...} ``` The easiest way to work with these types in Rust is to box them into a diff --git a/docs/overview/unstable_features.md b/docs/overview/unstable_features.md index 76d0d7d6d..ee9edf442 100644 --- a/docs/overview/unstable_features.md +++ b/docs/overview/unstable_features.md @@ -249,7 +249,7 @@ results in, for example, the following API differences: `X` is rust-movable | `X` is not rust-movable -------------------- | --------------------------------------- -`pub fn foo() -> X` | `pub fn foo() -> impl Ctor` +`pub fn foo() -> X` | `pub fn foo() -> Ctor!` `impl Add for &C` | `impl> Add for &C` The problem comes in with operator overloading: the following is valid: diff --git a/rs_bindings_from_cc/generate_bindings/generate_function.rs b/rs_bindings_from_cc/generate_bindings/generate_function.rs index 569a1c7fc..f1d8c152e 100644 --- a/rs_bindings_from_cc/generate_bindings/generate_function.rs +++ b/rs_bindings_from_cc/generate_bindings/generate_function.rs @@ -861,7 +861,7 @@ fn api_func_shape_for_constructor( /// Returns the shape of the generated Rust API for a given function definition. /// /// If the shape is a trait, this also mutates the parameter types to be -/// trait-compatible. In particular, types which would be `impl Ctor` +/// trait-compatible. In particular, types which would be `Ctor![T]` /// become a `RvalueReference<'_, T>`. /// /// Returns: @@ -1838,8 +1838,8 @@ struct BindingsSignature { /// The return type fragment of the Rust function, as a token stream. /// /// This is the same as the actual return type, except that () is the empty - /// tokens, non-Unpin by-value types are `impl Ctor + - /// ...`, and wherever the type is the type of `Self`, it gets replaced by + /// tokens, non-Unpin by-value types are `Ctor![#return_type] + ...`, + /// and wherever the type is the type of `Self`, it gets replaced by /// literal `Self`. return_type_fragment: TokenStream, @@ -1926,7 +1926,7 @@ fn function_signature( type_.to_token_stream_with_owned_ptr_type(db) }; *features |= Feature::impl_trait_in_assoc_type; - api_params.push(quote! {#ident: impl ::ctor::Ctor}); + api_params.push(quote! {#ident: ::ctor::Ctor![#quoted_type_or_self]}); thunk_args .push(quote! {::core::pin::Pin::into_inner_unchecked(::ctor::emplace!(#ident))}); } else { @@ -2036,31 +2036,37 @@ fn function_signature( Some(TraitName::Other { .. }) | None => {} } - let return_type_fragment = - if matches!(return_type.unalias(), RsTypeKind::Primitive(Primitive::Void)) { - quote! {} + let return_type_fragment = if matches!( + return_type.unalias(), + RsTypeKind::Primitive(Primitive::Void) + ) { + quote! {} + } else { + let ty = quoted_return_type + .unwrap_or_else(|| return_type.to_token_stream_with_owned_ptr_type(db)); + if return_type.is_unpin() { + ty } else { - let ty = quoted_return_type - .unwrap_or_else(|| return_type.to_token_stream_with_owned_ptr_type(db)); - if return_type.is_unpin() { - ty + // TODO(jeanpierreda): use `-> impl Ctor` instead of `-> Self::X` where `X = impl + // Ctor`. The latter requires `impl_trait_in_assoc_type`, the former + // was stabilized in 1.75. Directly returning an unnameable `impl + // Ctor` is sufficient for us, and makes traits like `CtorNew` more + // similar to top-level functions.) + + // The returned lazy FnCtor depends on all inputs. + let extra_lifetimes = if lifetimes.is_empty() { + quote! {} + } else { + quote! {+ use<#(#lifetimes),*> } + }; + *features |= Feature::impl_trait_in_assoc_type; + if extra_lifetimes.is_empty() { + quote! {::ctor::Ctor![#ty]} } else { - // TODO(jeanpierreda): use `-> impl Ctor` instead of `-> Self::X` where `X = impl - // Ctor`. The latter requires `impl_trait_in_assoc_type`, the former - // was stabilized in 1.75. Directly returning an unnameable `impl - // Ctor` is sufficient for us, and makes traits like `CtorNew` more - // similar to top-level functions.) - - // The returned lazy FnCtor depends on all inputs. - let extra_lifetimes = if lifetimes.is_empty() { - quote! {} - } else { - quote! {+ use<#(#lifetimes),*> } - }; - *features |= Feature::impl_trait_in_assoc_type; quote! {impl ::ctor::Ctor #extra_lifetimes } } - }; + } + }; // Change `__this: &'a SomeStruct` into `&'a self` if needed. if impl_kind.format_first_param_as_self() { 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 97ebaf698..d567b54f2 100644 --- a/rs_bindings_from_cc/generate_bindings/generate_function_test.rs +++ b/rs_bindings_from_cc/generate_bindings/generate_function_test.rs @@ -1449,7 +1449,7 @@ fn test_nonunpin_0_arg_constructor() -> Result<()> { rs_api, quote! { impl ::ctor::CtorNew<()> for HasConstructor { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] @@ -1483,7 +1483,7 @@ fn test_nonunpin_1_arg_constructor() -> Result<()> { rs_api, quote! { impl ::ctor::CtorNew<::core::ffi::c_uchar> for HasConstructor { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline (always)] @@ -1517,7 +1517,7 @@ fn test_nonunpin_2_arg_constructor() -> Result<()> { rs_api, quote! { impl ::ctor::CtorNew<(::core::ffi::c_uchar, ::core::ffi::c_schar)> for HasConstructor { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline (always)] @@ -1876,7 +1876,7 @@ fn test_nonunpin_param() -> Result<()> { assert_rs_matches!( rs_api, quote! { - pub fn TakesByValue(x: impl ::ctor::Ctor) { + pub fn TakesByValue(x: ::ctor::Ctor![crate::Nontrivial]) { unsafe { crate::detail::__rust_thunk___Z12TakesByValue10Nontrivial(::core::pin::Pin::into_inner_unchecked(::ctor::emplace!(x))) } 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 91e5023eb..1152dd212 100644 --- a/rs_bindings_from_cc/test/golden/inheritance_rs_api.rs +++ b/rs_bindings_from_cc/test/golden/inheritance_rs_api.rs @@ -215,7 +215,7 @@ unsafe impl ::cxx::ExternType for VirtualBase1 { } impl ::ctor::CtorNew<()> for VirtualBase1 { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { @@ -262,7 +262,7 @@ unsafe impl ::cxx::ExternType for VirtualBase2 { } impl ::ctor::CtorNew<()> for VirtualBase2 { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { @@ -309,7 +309,7 @@ unsafe impl ::cxx::ExternType for VirtualDerived { } impl ::ctor::CtorNew<()> for VirtualDerived { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { 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 b6d138562..b05082382 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 @@ -181,7 +181,7 @@ unsafe impl ::cxx::ExternType for FieldInTailPadding_InnerStruct { } impl ::ctor::CtorNew<()> for FieldInTailPadding_InnerStruct { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { @@ -268,7 +268,7 @@ impl ::ctor::PinnedDrop for FieldInTailPadding { impl ::ctor::CtorNew<(::core::ffi::c_int, ::core::ffi::c_char, ::core::ffi::c_char)> for FieldInTailPadding { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new( 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 5baeedef9..11e1088fc 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 @@ -40,7 +40,7 @@ unsafe impl ::cxx::ExternType for Nontrivial { } impl ::ctor::CtorNew<()> for Nontrivial { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { @@ -54,7 +54,7 @@ impl ::ctor::CtorNew<()> for Nontrivial { } impl ::ctor::CtorNew<::core::ffi::c_int> for Nontrivial { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ::core::ffi::c_int) -> Self::CtorType { @@ -70,7 +70,7 @@ impl ::ctor::CtorNew<::core::ffi::c_int> for Nontrivial { } } impl ::ctor::CtorNew<(::core::ffi::c_int,)> for Nontrivial { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: (::core::ffi::c_int,)) -> Self::CtorType { @@ -80,7 +80,7 @@ impl ::ctor::CtorNew<(::core::ffi::c_int,)> for Nontrivial { } impl ::ctor::CtorNew<(::core::ffi::c_int, ::core::ffi::c_int)> for Nontrivial { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: (::core::ffi::c_int, ::core::ffi::c_int)) -> Self::CtorType { @@ -214,7 +214,7 @@ unsafe impl ::cxx::ExternType for NontrivialInline { } impl ::ctor::CtorNew<()> for NontrivialInline { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { @@ -230,7 +230,7 @@ impl ::ctor::CtorNew<()> for NontrivialInline { } impl ::ctor::CtorNew<::core::ffi::c_int> for NontrivialInline { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ::core::ffi::c_int) -> Self::CtorType { @@ -246,7 +246,7 @@ impl ::ctor::CtorNew<::core::ffi::c_int> for NontrivialInline { } } impl ::ctor::CtorNew<(::core::ffi::c_int,)> for NontrivialInline { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: (::core::ffi::c_int,)) -> Self::CtorType { @@ -256,7 +256,7 @@ impl ::ctor::CtorNew<(::core::ffi::c_int,)> for NontrivialInline { } impl ::ctor::CtorNew<(::core::ffi::c_int, ::core::ffi::c_int)> for NontrivialInline { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: (::core::ffi::c_int, ::core::ffi::c_int)) -> Self::CtorType { @@ -330,7 +330,7 @@ unsafe impl ::cxx::ExternType for NontrivialMembers { } impl ::ctor::CtorNew<()> for NontrivialMembers { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { @@ -459,8 +459,8 @@ impl NontrivialUnpin { #[inline(always)] pub fn TakesByValue( - nontrivial: impl ::ctor::Ctor, -) -> impl ::ctor::Ctor { + nontrivial: ::ctor::Ctor![crate::Nontrivial], +) -> ::ctor::Ctor![crate::Nontrivial] { unsafe { ::ctor::FnCtor::new(move |dest: *mut crate::Nontrivial| { crate::detail::__rust_thunk___Z12TakesByValue10Nontrivial( @@ -473,8 +473,8 @@ pub fn TakesByValue( #[inline(always)] pub fn TakesByValueInline( - nontrivial: impl ::ctor::Ctor, -) -> impl ::ctor::Ctor { + nontrivial: ::ctor::Ctor![crate::NontrivialInline], +) -> ::ctor::Ctor![crate::NontrivialInline] { unsafe { ::ctor::FnCtor::new(move |dest: *mut crate::NontrivialInline| { crate::detail::__rust_thunk___Z18TakesByValueInline16NontrivialInline( @@ -618,7 +618,7 @@ unsafe impl ::cxx::ExternType for Nonmovable { } impl ::ctor::CtorNew<()> for Nonmovable { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { @@ -650,9 +650,8 @@ impl Nonmovable { )] pub trait BindingFailedFor_Z22TakesNonmovableByValue10Nonmovable {} #[inline(always)] -pub fn TakesNonmovableByValue<'error>( - nonmovable: impl ::ctor::Ctor, -) where +pub fn TakesNonmovableByValue<'error>(nonmovable: ::ctor::Ctor![crate::Nonmovable]) +where &'error (): BindingFailedFor_Z22TakesNonmovableByValue10Nonmovable, { #![allow(unused_variables)] @@ -663,8 +662,7 @@ pub fn TakesNonmovableByValue<'error>( } #[inline(always)] -pub fn ReturnsNonmovableByValue( -) -> impl ::ctor::Ctor { +pub fn ReturnsNonmovableByValue() -> ::ctor::Ctor![crate::Nonmovable] { unsafe { ::ctor::FnCtor::new(move |dest: *mut crate::Nonmovable| { crate::detail::__rust_thunk___Z24ReturnsNonmovableByValuev( 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 d045a061e..c732ac19e 100644 --- a/rs_bindings_from_cc/test/golden/operators_rs_api.rs +++ b/rs_bindings_from_cc/test/golden/operators_rs_api.rs @@ -529,7 +529,7 @@ unsafe impl ::cxx::ExternType for AddableConstMemberNonunpin { } impl ::ctor::CtorNew<()> for AddableConstMemberNonunpin { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { 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 9e1a7d971..00aee4d94 100644 --- a/rs_bindings_from_cc/test/golden/polymorphic_rs_api.rs +++ b/rs_bindings_from_cc/test/golden/polymorphic_rs_api.rs @@ -34,7 +34,7 @@ unsafe impl ::cxx::ExternType for PolymorphicBase { } impl ::ctor::CtorNew<()> for PolymorphicBase { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { @@ -79,7 +79,7 @@ unsafe impl ::cxx::ExternType for PolymorphicBase2 { } impl ::ctor::CtorNew<()> for PolymorphicBase2 { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { @@ -131,7 +131,7 @@ unsafe impl ::cxx::ExternType for PolymorphicDerived { } impl ::ctor::CtorNew<()> for PolymorphicDerived { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { 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 c0b6734f1..f21d6ff9a 100644 --- a/rs_bindings_from_cc/test/golden/unions_rs_api.rs +++ b/rs_bindings_from_cc/test/golden/unions_rs_api.rs @@ -77,7 +77,7 @@ unsafe impl ::cxx::ExternType for Nontrivial { } impl ::ctor::CtorNew<()> for Nontrivial { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { 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 baa4f2bbb..5e721db6f 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,7 +40,7 @@ unsafe impl ::cxx::ExternType for Derived2 { } impl ::ctor::CtorNew<()> for Derived2 { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { @@ -85,7 +85,7 @@ unsafe impl ::cxx::ExternType for VirtualDerived2 { } impl ::ctor::CtorNew<()> for VirtualDerived2 { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { diff --git a/rs_bindings_from_cc/test/golden/user_of_unsupported_rs_api.rs b/rs_bindings_from_cc/test/golden/user_of_unsupported_rs_api.rs index 634708f7e..46c123fee 100644 --- a/rs_bindings_from_cc/test/golden/user_of_unsupported_rs_api.rs +++ b/rs_bindings_from_cc/test/golden/user_of_unsupported_rs_api.rs @@ -16,10 +16,7 @@ #[inline(always)] pub fn UseNontrivialCustomType( - non_trivial_custom_type: impl ::ctor::Ctor< - Output = ::unsupported_cc::NontrivialCustomType, - Error = ::ctor::Infallible, - >, + non_trivial_custom_type: ::ctor::Ctor![::unsupported_cc::NontrivialCustomType], ) { unsafe { crate::detail::__rust_thunk___Z23UseNontrivialCustomType20NontrivialCustomType( 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 a86de1678..b296fb332 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,7 +37,7 @@ unsafe impl ::cxx::ExternType for Uncopyable { /// Generated from: rs_bindings_from_cc/test/struct/default_member_functions/default_member_functions.h;l=12 impl ::ctor::CtorNew<()> for Uncopyable { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { @@ -81,7 +81,7 @@ impl ::ctor::PinnedDrop for UncopyableDespiteDecl { /// Generated from: rs_bindings_from_cc/test/struct/default_member_functions/default_member_functions.h;l=19 impl ::ctor::CtorNew<()> for UncopyableDespiteDecl { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { 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 ef5e6c1ae..5e03aa77b 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,7 +38,7 @@ forward_declare::unsafe_define!(forward_declare::symbol!("Nonmovable"), crate::N /// Generated from: rs_bindings_from_cc/test/struct/inheritance/inherited_methods.h;l=11 impl ::ctor::CtorNew<()> for Nonmovable { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ()) -> Self::CtorType { @@ -96,10 +96,7 @@ where { /// Generated from: rs_bindings_from_cc/test/struct/inheritance/inherited_methods.h;l=19 #[inline(always)] - pub fn no_bindings<'a>( - &'a self, - __param_0: impl ::ctor::Ctor, - ) { + pub fn no_bindings<'a>(&'a self, __param_0: ::ctor::Ctor![crate::Nonmovable]) { #![allow(unused_variables)] unreachable!( "This impl can never be instantiated. \ @@ -155,10 +152,7 @@ where { /// Generated from: rs_bindings_from_cc/test/struct/inheritance/inherited_methods.h;l=19 #[inline(always)] - pub fn no_bindings<'a>( - &'a self, - __param_0: impl ::ctor::Ctor, - ) { + pub fn no_bindings<'a>(&'a self, __param_0: ::ctor::Ctor![crate::Nonmovable]) { #![allow(unused_variables)] unreachable!( "This impl can never be instantiated. \ 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 1f5db6098..6645ab24c 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,7 +39,7 @@ forward_declare::unsafe_define!(forward_declare::symbol!("Nontrivial"), crate::N /// Generated from: rs_bindings_from_cc/test/wrapper/impl_ctor/impl_ctor.h;l=10 impl ::ctor::CtorNew<::core::ffi::c_int> for Nontrivial { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: ::core::ffi::c_int) -> Self::CtorType { @@ -55,7 +55,7 @@ impl ::ctor::CtorNew<::core::ffi::c_int> for Nontrivial { } } impl ::ctor::CtorNew<(::core::ffi::c_int,)> for Nontrivial { - type CtorType = impl ::ctor::Ctor; + type CtorType = ::ctor::Ctor![Self]; type Error = ::ctor::Infallible; #[inline(always)] fn ctor_new(args: (::core::ffi::c_int,)) -> Self::CtorType { @@ -111,7 +111,7 @@ impl ::ctor::PinnedDrop for Nontrivial { /// Generated from: rs_bindings_from_cc/test/wrapper/impl_ctor/impl_ctor.h;l=16 #[inline(always)] -pub fn Create() -> impl ::ctor::Ctor { +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); @@ -121,9 +121,7 @@ pub fn Create() -> impl ::ctor::Ctor, -) -> ::core::ffi::c_int { +pub fn Read(nontrivial: ::ctor::Ctor![crate::Nontrivial]) -> ::core::ffi::c_int { unsafe { crate::detail::__rust_thunk___Z4Read10Nontrivial(::core::pin::Pin::into_inner_unchecked( ::ctor::emplace!(nontrivial), diff --git a/support/ctor.rs b/support/ctor.rs index b8e450d80..58342fcad 100644 --- a/support/ctor.rs +++ b/support/ctor.rs @@ -188,6 +188,9 @@ macro_rules! must_use_ctor_assign { /// In-place initialization of a value. /// +/// This is commonly used as `impl Ctor`, in function parameters or +/// return types, and can be spelled `Ctor![T]`. +/// /// # Safety /// /// Implementations must satisfy the postconditions of the `ctor` method. @@ -215,7 +218,7 @@ pub unsafe trait Ctor: Sized { /// /// This is useful for chaining possibly-fallible operations (such as `ctor_then`) on top of /// an existing infallible `Ctor`. - fn ctor_make_fallible(self) -> impl Ctor + fn ctor_make_fallible(self) -> Ctor![Self::Output, Error = E] where Self: Ctor, { @@ -223,7 +226,7 @@ pub unsafe trait Ctor: Sized { } /// Maps this `Ctor`'s error type into a new error type using the `Into` trait. - fn ctor_err_into(self) -> impl Ctor + fn ctor_err_into(self) -> Ctor![Self::Output, Error = E] where Self::Error: Into, { @@ -248,7 +251,7 @@ pub unsafe trait Ctor: Sized { /// }); /// let x = emplace!(new_ctor); /// ``` - fn ctor_then(self, f: F) -> impl Ctor + fn ctor_then(self, f: F) -> Ctor![Self::Output, Error = Self::Error] where F: FnOnce(Pin<&mut Self::Output>) -> Result<(), Self::Error>, { @@ -296,7 +299,7 @@ pub unsafe trait Ctor: Sized { /// let new_ctor = y.ctor_map_err(|e| e.into_new_error()); /// let x = try_emplace!(new_ctor); /// ``` - fn ctor_map_err(self, f: F) -> impl Ctor + fn ctor_map_err(self, f: F) -> Ctor![Self::Output, Error = E] where F: FnOnce(Self::Error) -> E, { @@ -314,7 +317,7 @@ pub unsafe trait Ctor: Sized { /// let new_ctor = Y::first_attempt().ctor_or_else(|_| Y::fallback_attempt()); /// let x = try_emplace!(new_ctor); /// ``` - fn ctor_or_else(self, f: F) -> impl Ctor + fn ctor_or_else(self, f: F) -> Ctor![Self::Output, Error = O::Error] where F: FnOnce(Self::Error) -> O, O: Ctor, @@ -374,7 +377,7 @@ pub unsafe trait Ctor: Sized { /// Returns a `Ctor` which will panic if the original construction fails. /// /// This functions similarly to `Result::unwrap`. - fn ctor_unwrap(self) -> impl Ctor + fn ctor_unwrap(self) -> Ctor![Self::Output, Error = Infallible] where Self::Error: Debug, { @@ -393,7 +396,7 @@ pub unsafe trait Ctor: Sized { /// This functions similarly to `Result::unwrap_or_default`. fn ctor_unwrap_or_default( self, - ) -> impl Ctor>::Error> + ) -> Ctor![Self::Output, Error = >::Error] where Self::Output: CtorNew<()>, { @@ -401,6 +404,29 @@ pub unsafe trait Ctor: Sized { } } +/// The type macro for an `impl Ctor<...>`, used as a parameter or return type. +/// +/// This exists for two reasons: +/// +/// 1. To allow for changing the implementation over time. +/// 2. To make the spelling less overly verbose. Instead of `impl Ctor`, +/// you can write `Ctor![T]`. +/// +/// In codebases not yet migrated to the 2024 edition, if you need a `use<'a>` bound, you must +/// write the full `impl` syntax: +/// `impl Ctor + use<'a, 'b>`. +/// +/// (It is surprisingly difficult to write a macro that would allow the `use` parameters!) +#[macro_export] +macro_rules! Ctor { + ( $T:ty $(,)?) => { + impl $crate::Ctor + }; + ( $T:ty, Error = $E:ty $(,)?) => { + impl $crate::Ctor + }; +} + /// Returns a `Ctor` with error type `E` which always fails with the given error. pub fn ctor_error(e: E) -> impl Ctor { struct CtorError { @@ -1028,6 +1054,7 @@ impl Slot { #[doc(hidden)] pub mod macro_internal { use super::*; + pub use crate::Infallible; pub use core::mem::MaybeUninit; pub use core::pin::Pin;