Derive movability and destruction of an existing Rust type from its type arguments. - #2044
Open
copybara-service[bot] wants to merge 1 commit into
Open
copybara-service[bot] wants to merge 1 commit into
copybara-service[bot] wants to merge 1 commit into
Conversation
…ype arguments.
`RsTypeKind::ExistingRustType` interpolated its template arguments into the
spelling of the Rust type and then threw them away. As a result, every generic
mapped through `CRUBIT_INTERNAL_RUST_TYPE` was reported as `Unpin` and as not
needing destruction, no matter what it was instantiated with.
This is wrong for a generic that stores its payload in place. The motivating
case is `absl::StatusOr<T>` under `CRUBIT_NEW_STATUS`, which is mapped onto
`status::absl::NewStatusOr<T>`. `NewStatusOr<T>` holds a `MaybeUninit<T>`
inline and has an unconditional `Drop` impl, so `NewStatusOr<T>` is `!Unpin`
whenever `T` is. With the `layout_compat_string` feature enabled,
`absl::StatusOr<std::string>` maps onto `NewStatusOr<cc_std::std::string>`, and
Crubit was generating a by-value return:
```rust
pub fn MakeStringOrError() -> ::status::absl::NewStatusOr<::cc_std::std::string> {
...
__crubit_return.assume_init() // relocates a C++ `std::string`
}
```
This happens to work today only because libc++'s `std::string` is trivially
relocatable in practice; it is not something Crubit is entitled to assume.
Retain the type arguments on `ExistingRustType` and consult them from
`is_unpin` and `needs_destruction`, via a new `RsTypeKind::inline_payloads`.
The example above now returns
`-> ::ctor::Ctor![::status::absl::NewStatusOr<::cc_std::std::string>]`.
Type arguments of a `UniformReprTemplateType` (`std::vector<T>`,
`std::unique_ptr<T>`, ...) and of a bridged container are deliberately not
treated as inline payloads: those either keep the payload behind indirection or
already require it to be Rust-movable.
This is complementary to the `layout_compat_optional` work in unknown commit,
which fixes the same class of bug for `std::optional<T>` on the
`UniformReprTemplateType` path.
PiperOrigin-RevId: 982826786
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Derive movability and destruction of an existing Rust type from its type arguments.
RsTypeKind::ExistingRustTypeinterpolated its template arguments into thespelling of the Rust type and then threw them away. As a result, every generic
mapped through
CRUBIT_INTERNAL_RUST_TYPEwas reported asUnpinand as notneeding destruction, no matter what it was instantiated with.
This is wrong for a generic that stores its payload in place. The motivating
case is
absl::StatusOr<T>underCRUBIT_NEW_STATUS, which is mapped ontostatus::absl::NewStatusOr<T>.NewStatusOr<T>holds aMaybeUninit<T>inline and has an unconditional
Dropimpl, soNewStatusOr<T>is!Unpinwhenever
Tis. With thelayout_compat_stringfeature enabled,absl::StatusOr<std::string>maps ontoNewStatusOr<cc_std::std::string>, andCrubit was generating a by-value return:
This happens to work today only because libc++'s
std::stringis triviallyrelocatable in practice; it is not something Crubit is entitled to assume.
Retain the type arguments on
ExistingRustTypeand consult them fromis_unpinandneeds_destruction, via a newRsTypeKind::inline_payloads.The example above now returns
-> ::ctor::Ctor![::status::absl::NewStatusOr<::cc_std::std::string>].Type arguments of a
UniformReprTemplateType(std::vector<T>,std::unique_ptr<T>, ...) and of a bridged container are deliberately nottreated as inline payloads: those either keep the payload behind indirection or
already require it to be Rust-movable.
This is complementary to the
layout_compat_optionalwork in unknown commit,which fixes the same class of bug for
std::optional<T>on theUniformReprTemplateTypepath.