Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions docs/cpp/non_rust_movable.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ support/ctor.rs

`Ctor<Output=T, Error=E>` 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<Output=T, ...>`, 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.
Expand All @@ -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<Output=CppType, ...>) {...}
pub fn returns() -> impl Ctor<Output=CppType, ...> {...}
pub fn accepts_value(x: Ctor![CppType]) {...}
// equivalent to x: impl Ctor<Output=CppType, Error=Infallible>
pub fn returns() -> Ctor![CppType] {...}
```

The easiest way to work with these types in Rust is to box them into a
Expand Down
2 changes: 1 addition & 1 deletion docs/overview/unstable_features.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<Output=X>`
`pub fn foo() -> X` | `pub fn foo() -> Ctor!<Output=X>`
`impl Add<X> for &C` | `impl<T: Ctor<Output=X>> Add<T> for &C`

The problem comes in with operator overloading: the following is valid:
Expand Down
56 changes: 31 additions & 25 deletions rs_bindings_from_cc/generate_bindings/generate_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Output=T>`
/// trait-compatible. In particular, types which would be `Ctor![T]`
/// become a `RvalueReference<'_, T>`.
///
/// Returns:
Expand Down Expand Up @@ -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<Output=#return_type> +
/// ...`, 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,

Expand Down Expand Up @@ -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<Output=#quoted_type_or_self, Error=::ctor::Infallible>});
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 {
Expand Down Expand Up @@ -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<Output=#ty, Error=::ctor::Infallible> #extra_lifetimes }
}
};
}
};

// Change `__this: &'a SomeStruct` into `&'a self` if needed.
if impl_kind.format_first_param_as_self() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1449,7 +1449,7 @@ fn test_nonunpin_0_arg_constructor() -> Result<()> {
rs_api,
quote! {
impl ::ctor::CtorNew<()> for HasConstructor {
type CtorType = impl ::ctor::Ctor<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;

#[inline(always)]
Expand Down Expand Up @@ -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<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;

#[inline (always)]
Expand Down Expand Up @@ -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<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;

#[inline (always)]
Expand Down Expand Up @@ -1876,7 +1876,7 @@ fn test_nonunpin_param() -> Result<()> {
assert_rs_matches!(
rs_api,
quote! {
pub fn TakesByValue(x: impl ::ctor::Ctor<Output=crate::Nontrivial, Error=::ctor::Infallible>) {
pub fn TakesByValue(x: ::ctor::Ctor![crate::Nontrivial]) {
unsafe {
crate::detail::__rust_thunk___Z12TakesByValue10Nontrivial(::core::pin::Pin::into_inner_unchecked(::ctor::emplace!(x)))
}
Expand Down
6 changes: 3 additions & 3 deletions rs_bindings_from_cc/test/golden/inheritance_rs_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ unsafe impl ::cxx::ExternType for VirtualBase1 {
}

impl ::ctor::CtorNew<()> for VirtualBase1 {
type CtorType = impl ::ctor::Ctor<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: ()) -> Self::CtorType {
Expand Down Expand Up @@ -262,7 +262,7 @@ unsafe impl ::cxx::ExternType for VirtualBase2 {
}

impl ::ctor::CtorNew<()> for VirtualBase2 {
type CtorType = impl ::ctor::Ctor<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: ()) -> Self::CtorType {
Expand Down Expand Up @@ -309,7 +309,7 @@ unsafe impl ::cxx::ExternType for VirtualDerived {
}

impl ::ctor::CtorNew<()> for VirtualDerived {
type CtorType = impl ::ctor::Ctor<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: ()) -> Self::CtorType {
Expand Down
4 changes: 2 additions & 2 deletions rs_bindings_from_cc/test/golden/no_unique_address_rs_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ unsafe impl ::cxx::ExternType for FieldInTailPadding_InnerStruct {
}

impl ::ctor::CtorNew<()> for FieldInTailPadding_InnerStruct {
type CtorType = impl ::ctor::Ctor<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: ()) -> Self::CtorType {
Expand Down Expand Up @@ -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<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(
Expand Down
36 changes: 17 additions & 19 deletions rs_bindings_from_cc/test/golden/nontrivial_type_rs_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ unsafe impl ::cxx::ExternType for Nontrivial {
}

impl ::ctor::CtorNew<()> for Nontrivial {
type CtorType = impl ::ctor::Ctor<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: ()) -> Self::CtorType {
Expand All @@ -54,7 +54,7 @@ impl ::ctor::CtorNew<()> for Nontrivial {
}

impl ::ctor::CtorNew<::core::ffi::c_int> for Nontrivial {
type CtorType = impl ::ctor::Ctor<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: ::core::ffi::c_int) -> Self::CtorType {
Expand All @@ -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<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: (::core::ffi::c_int,)) -> Self::CtorType {
Expand All @@ -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<Output = Self, Error = ::ctor::Infallible>;
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 {
Expand Down Expand Up @@ -214,7 +214,7 @@ unsafe impl ::cxx::ExternType for NontrivialInline {
}

impl ::ctor::CtorNew<()> for NontrivialInline {
type CtorType = impl ::ctor::Ctor<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: ()) -> Self::CtorType {
Expand All @@ -230,7 +230,7 @@ impl ::ctor::CtorNew<()> for NontrivialInline {
}

impl ::ctor::CtorNew<::core::ffi::c_int> for NontrivialInline {
type CtorType = impl ::ctor::Ctor<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: ::core::ffi::c_int) -> Self::CtorType {
Expand All @@ -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<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: (::core::ffi::c_int,)) -> Self::CtorType {
Expand All @@ -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<Output = Self, Error = ::ctor::Infallible>;
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 {
Expand Down Expand Up @@ -330,7 +330,7 @@ unsafe impl ::cxx::ExternType for NontrivialMembers {
}

impl ::ctor::CtorNew<()> for NontrivialMembers {
type CtorType = impl ::ctor::Ctor<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: ()) -> Self::CtorType {
Expand Down Expand Up @@ -459,8 +459,8 @@ impl NontrivialUnpin {

#[inline(always)]
pub fn TakesByValue(
nontrivial: impl ::ctor::Ctor<Output = crate::Nontrivial, Error = ::ctor::Infallible>,
) -> impl ::ctor::Ctor<Output = crate::Nontrivial, Error = ::ctor::Infallible> {
nontrivial: ::ctor::Ctor![crate::Nontrivial],
) -> ::ctor::Ctor![crate::Nontrivial] {
unsafe {
::ctor::FnCtor::new(move |dest: *mut crate::Nontrivial| {
crate::detail::__rust_thunk___Z12TakesByValue10Nontrivial(
Expand All @@ -473,8 +473,8 @@ pub fn TakesByValue(

#[inline(always)]
pub fn TakesByValueInline(
nontrivial: impl ::ctor::Ctor<Output = crate::NontrivialInline, Error = ::ctor::Infallible>,
) -> impl ::ctor::Ctor<Output = crate::NontrivialInline, Error = ::ctor::Infallible> {
nontrivial: ::ctor::Ctor![crate::NontrivialInline],
) -> ::ctor::Ctor![crate::NontrivialInline] {
unsafe {
::ctor::FnCtor::new(move |dest: *mut crate::NontrivialInline| {
crate::detail::__rust_thunk___Z18TakesByValueInline16NontrivialInline(
Expand Down Expand Up @@ -618,7 +618,7 @@ unsafe impl ::cxx::ExternType for Nonmovable {
}

impl ::ctor::CtorNew<()> for Nonmovable {
type CtorType = impl ::ctor::Ctor<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: ()) -> Self::CtorType {
Expand Down Expand Up @@ -650,9 +650,8 @@ impl Nonmovable {
)]
pub trait BindingFailedFor_Z22TakesNonmovableByValue10Nonmovable {}
#[inline(always)]
pub fn TakesNonmovableByValue<'error>(
nonmovable: impl ::ctor::Ctor<Output = crate::Nonmovable, Error = ::ctor::Infallible>,
) where
pub fn TakesNonmovableByValue<'error>(nonmovable: ::ctor::Ctor![crate::Nonmovable])
where
&'error (): BindingFailedFor_Z22TakesNonmovableByValue10Nonmovable,
{
#![allow(unused_variables)]
Expand All @@ -663,8 +662,7 @@ pub fn TakesNonmovableByValue<'error>(
}

#[inline(always)]
pub fn ReturnsNonmovableByValue(
) -> impl ::ctor::Ctor<Output = crate::Nonmovable, Error = ::ctor::Infallible> {
pub fn ReturnsNonmovableByValue() -> ::ctor::Ctor![crate::Nonmovable] {
unsafe {
::ctor::FnCtor::new(move |dest: *mut crate::Nonmovable| {
crate::detail::__rust_thunk___Z24ReturnsNonmovableByValuev(
Expand Down
2 changes: 1 addition & 1 deletion rs_bindings_from_cc/test/golden/operators_rs_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ unsafe impl ::cxx::ExternType for AddableConstMemberNonunpin {
}

impl ::ctor::CtorNew<()> for AddableConstMemberNonunpin {
type CtorType = impl ::ctor::Ctor<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: ()) -> Self::CtorType {
Expand Down
6 changes: 3 additions & 3 deletions rs_bindings_from_cc/test/golden/polymorphic_rs_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ unsafe impl ::cxx::ExternType for PolymorphicBase {
}

impl ::ctor::CtorNew<()> for PolymorphicBase {
type CtorType = impl ::ctor::Ctor<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: ()) -> Self::CtorType {
Expand Down Expand Up @@ -79,7 +79,7 @@ unsafe impl ::cxx::ExternType for PolymorphicBase2 {
}

impl ::ctor::CtorNew<()> for PolymorphicBase2 {
type CtorType = impl ::ctor::Ctor<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: ()) -> Self::CtorType {
Expand Down Expand Up @@ -131,7 +131,7 @@ unsafe impl ::cxx::ExternType for PolymorphicDerived {
}

impl ::ctor::CtorNew<()> for PolymorphicDerived {
type CtorType = impl ::ctor::Ctor<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: ()) -> Self::CtorType {
Expand Down
2 changes: 1 addition & 1 deletion rs_bindings_from_cc/test/golden/unions_rs_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ unsafe impl ::cxx::ExternType for Nontrivial {
}

impl ::ctor::CtorNew<()> for Nontrivial {
type CtorType = impl ::ctor::Ctor<Output = Self, Error = ::ctor::Infallible>;
type CtorType = ::ctor::Ctor![Self];
type Error = ::ctor::Infallible;
#[inline(always)]
fn ctor_new(args: ()) -> Self::CtorType {
Expand Down
Loading
Loading