Skip to content

What rule prevents me from Copying arbitrary ZSTs? #47255

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

Closed
scottmcm opened this issue Jan 7, 2018 · 2 comments
Closed

What rule prevents me from Copying arbitrary ZSTs? #47255

scottmcm opened this issue Jan 7, 2018 · 2 comments

Comments

@scottmcm
Copy link
Member

scottmcm commented Jan 7, 2018

What makes the clone_token function in this code example illegal? https://play.rust-lang.org/?gist=f284d059d2ec79b770e887654c402be3&version=nightly

It certainly feels like it ought to be illegal.

But it's not violating any of the usual rules: it's not a data race, the objects sizes match, the alignment requirements are met, it produces an object containing a valid bit pattern for the type, it meets all the lifetime and mutability requirements, ...

Is there a rule I forgot?

@hanna-kruppe
Copy link
Contributor

hanna-kruppe commented Jan 7, 2018

Unsafe code can do lots of things that don't immediately cause UB, yet which break assumptions other code might reasonably make (leading to UB in that code, or just undesirable behavior). Circumventing privacy as your example does is one of those, and it can cause many issues beyond ZSTs. You can also break invariants of non-ZST types, for example store a NaN value in a NotNaN newtype. You have to make assumptions about the private fields of the struct to do that, but your ZST example already does that (and fixes like asserting that the size is 0 can also be applied to some non-ZST cases).

Another example is that unsafe code can call setjmp and longjmp to skip over multiple stack frames without unwinding. This is incompatible with otherwise safe APIs such as rayon::join. This example is from a blog post by @nikomatsakis which is highly relevant to this issue.

I don't think there has been anywhere near as much effort to nail down these rules as there has been for the "what is UB" rules. Perhaps it's not even desirable to have just one such set of rules (see the blog post). But these rules will certainly be a strict superset of the rules for not causing UB. As @RalfJung said in rust-lang/rust-memory-model#44 (comment):

"What code is UB" and "What safe code can rely on unsafe code to (not) do" don't always have the same answer, though of course safe code can at least rely on unsafe code not triggering UB.

@bluss
Copy link
Member

bluss commented Jan 9, 2018

It was already said over in the other issue, but I think ownership semantics are violated here.

@scottmcm scottmcm closed this as completed Jan 9, 2018
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

No branches or pull requests

3 participants