Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweak wording of the triviality requirement #339

Merged
merged 1 commit into from
Oct 5, 2020
Merged

Tweak wording of the triviality requirement #339

merged 1 commit into from
Oct 5, 2020

Conversation

dtolnay
Copy link
Owner

@dtolnay dtolnay commented Oct 5, 2020

It isn't actually a requirement that the type have no destructor as brought up by the previous paragraph. Rather, it just needs to be safe for values of that type to be moved via Rust's memcpy-based move semantics.

The distinction is relevant e.g. for struct S { s: String } which would have a C++ destructor and nontrivial implicitly defined move constructor but still be safely memcpy movable. C++ has no analogue of "trivially destructive-movable" which is the semantic we are really interested in.

It isn't actually a requirement that the type have no destructor as
brought up by the previous paragraph. Rather, it just needs to be safe
for values of that type to be moved via Rust's memcpy-based move
semantics.

The distinction is relevant e.g. for `struct S { s: String }` which
would have a C++ destructor and nontrivial move constructor but still be
safely memcpy movable.
@dtolnay dtolnay requested a review from adetaylor October 5, 2020 20:33
@adetaylor
Copy link
Collaborator

struct S { s: String } is safely memcpy movable?

I assume you mean:

struct S {
  std::string s;
}

in C++ terms. My understanding is that std::string has a pointer which may or may not be self-referential, depending on the length of the string (and possibly the STL implementation?) so isn't safely memcpy-able.

(This wording's fine, though, of course!)

@dtolnay
Copy link
Owner Author

dtolnay commented Oct 5, 2020

No I do mean struct S { s: String }, with a Rust string, i.e. struct S { rust::String s; };. It is safely memcpy movable as long as your move semantics are destructive, as in Rust.

This is connected to the last paragraph of the comment in #338.

To support structs like this in #297 the is_trivially_move_constructible/is_trivially_destructible condition is going to need to change. I think I would prefer not to just outright remove the static assert, even though that would be sound (as justified by #338). Instead I think we are going to end up doing some template metaprogramming of our own to add a disjunction which we enable automatically for cxx-generated shared structs or a user could enable from C++ for their own struct. (I don't know exactly how; not a C++ expert.)

Pseudocode:

static_assert(rust::is_trivially_destructive_movable<T> // <- from rust/cxx.h
    || (std::is_trivially_move_constructible<T> && std::is_trivially_destructible<T>));

FYI @sbrocket as well.

@adetaylor
Copy link
Collaborator

I see.

I would strongly like to keep those static_asserts for C++ types if we can find a way. I agree that from a soundness perspective, it's moot because the user has made a promise. But from a practical perspective with a realistic mess of C++ types, it's really difficult for a developer to figure this stuff out, so I think those asserts are extremely valuable.

I think the plan of a new C++ template sounds like the right plan to me.

@dtolnay dtolnay merged commit 9420532 into master Oct 5, 2020
@dtolnay dtolnay deleted the triviality branch October 5, 2020 22:47
@dtolnay
Copy link
Owner Author

dtolnay commented Oct 5, 2020

I would strongly like to keep those static_asserts for C++ types if we can find a way. I agree that from a soundness perspective, it's moot because the user has made a promise. But from a practical perspective with a realistic mess of C++ types, it's really difficult for a developer to figure this stuff out, so I think those asserts are extremely valuable.

Understood. I agree with this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants