-
-
Notifications
You must be signed in to change notification settings - Fork 14.4k
Document & implement the transmutation modeled by BikeshedIntrinsicFrom
#129032
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
Conversation
b806b5e to
96cfefb
Compare
This comment has been minimized.
This comment has been minimized.
| /// This trait cannot be implemented explicitly. It is implemented on-the-fly by | ||
| /// the compiler for all types `Src` and `Self` such that, given a set of safety | ||
| /// obligations on the programmer (see [`Assume`]), the compiler has proved that | ||
| /// the bits of a value of type `Src` can be soundly reinterpreted as `Self`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| /// the bits of a value of type `Src` can be soundly reinterpreted as `Self`. | |
| /// the bits of a value of type `Src` can be soundly reinterpreted as a `Self`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't actually agree with this change. "as Self" sounds more correct in my idiolect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thinking is that the left-hand side refers to a runtime object - "a value of type Src" - and so the right-hand side should too. Conservatively, we could say "a value of type Self", but IIUC "a Self" is a common shorthand for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we take the Self part out for a moment, it would be common to say "as an i32", or "as an array", so "a Self" probably fits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| /// union Transmute<T, U> { | ||
| /// src: ManuallyDrop<T>, | ||
| /// dst: ManuallyDrop<U>, | ||
| /// } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| /// union Transmute<T, U> { | |
| /// src: ManuallyDrop<T>, | |
| /// dst: ManuallyDrop<U>, | |
| /// } | |
| /// union Transmute<S, D> { | |
| /// src: ManuallyDrop<S>, | |
| /// dst: ManuallyDrop<D>, | |
| /// } |
I assume your intention is to not confuse the reader by re-using Src and Dst? In that case, IMO using S and D makes the correspondence with Src and Dst clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hadn't put that much thought into this, actually. I don't think there's any risk of confusion from shadowing Src and Dst (even if you didn't realize they were shadowed, the meaning of the code wouldn't change), so I've opted to just use Src and Dst:
- https://github.com/rust-lang/rust/compare/96cfefbb125916871760c1df4c2ee29944635e90..1c0e7fac16490ea2e83ab0127c364231a42742ad#diff-85698661a7eb53801df364c9242c8613f7d2e4bca026bc5c88d542c22fa01ddfR21-R23
- https://github.com/rust-lang/rust/compare/96cfefbb125916871760c1df4c2ee29944635e90..1c0e7fac16490ea2e83ab0127c364231a42742ad#diff-85698661a7eb53801df364c9242c8613f7d2e4bca026bc5c88d542c22fa01ddfR114-R116
| /// Implementations of this trait do not provide any guarantee of portability | ||
| /// across toolchains or compilations. This trait may be implemented for certain | ||
| /// combinations of `Src`, `Self` and `ASSUME` on some toolchains, but not | ||
| /// others. For example, if the layouts of `Src` or `Self` are | ||
| /// non-deterministic, the presence or absence of an implementation of this | ||
| /// trait may also be non-deterministic. Even if `Src` and `Self` have | ||
| /// deterministic layouts (e.g., they are `repr(C)` structs), Rust does not | ||
| /// specify the alignments of its primitive integer types, and layouts that | ||
| /// involve these types may vary across toolchains. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also mention varying across target architecture and target OS? Both can affect alignment, and architecture can affect size (maybe OS can too? not sure).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! This now says "toolchains, targets or compilations".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One change left:
Rust does not specify the alignments of its primitive integer types, and layouts that involve these types may vary across toolchains.
This should say "across toolchains or targets" or something similar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| /// Note that this construction supports some transmutations forbidden by | ||
| /// [`mem::transmute_copy`](super::transmute_copy), namely transmutations that | ||
| /// extend the trailing padding of `Src` to fill `Dst`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This strikes me as a bit ambiguous. I'd clarify in particular that you're referring to a situation where:
size_of::<Src>() < size_of::<Dst>()- The trailing
size_of::<Dst>() - size_of::<Src>()bytes ofDstare permitted to be uninitialized (e.g., are padding)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've reworded this slightly, and included an example provided by @scottmcm on Zulip: https://github.com/rust-lang/rust/compare/96cfefbb125916871760c1df4c2ee29944635e90..1c0e7fac16490ea2e83ab0127c364231a42742ad#diff-85698661a7eb53801df364c9242c8613f7d2e4bca026bc5c88d542c22fa01ddfR59
| /// trait may also be non-deterministic. Even if `Src` and `Self` have | ||
| /// deterministic layouts (e.g., they are `repr(C)` structs), Rust does not | ||
| /// specify the alignments of its primitive integer types, and layouts that | ||
| /// involve these types may vary across toolchains. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would maybe phrase this as "stability hazards may exist" and mention the alignments of primitive types as one example of such hazards. Don't want to imply by omission that they're the only hazard.
96cfefb to
1c0e7fa
Compare
This comment has been minimized.
This comment has been minimized.
43dfc04 to
b17b899
Compare
This comment has been minimized.
This comment has been minimized.
b17b899 to
ac7b552
Compare
This comment has been minimized.
This comment has been minimized.
ac7b552 to
8bf3df9
Compare
joshlf
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few optional changes requested, but LGTM!
8bf3df9 to
7254d9d
Compare
7254d9d to
60cfa88
Compare
|
☔ The latest upstream changes (presumably #122551) made this pull request unmergeable. Please resolve the merge conflicts. |
60cfa88 to
c3ebec9
Compare
f31c502 to
5ab5080
Compare
|
@joshlf, could you take another look at this?
|
This comment has been minimized.
This comment has been minimized.
5ab5080 to
aa01623
Compare
This comment has been minimized.
This comment has been minimized.
Documents that `BikeshedIntrinsicFrom` models transmute-via-union, which is slightly more expressive than the transmute-via-cast implemented by `transmute_copy`. Additionally, we provide an implementation of transmute-via-union as a method on the `BikeshedIntrinsicFrom` trait with additional documentation on the boundary between trait invariants and caller obligations. Whether or not transmute-via-union is the right kind of transmute to model remains up for discussion [1]. Regardless, it seems wise to document the present behavior. [1] https://rust-lang.zulipchat.com/#narrow/stream/216762-project-safe-transmute/topic/What.20'kind'.20of.20transmute.20to.20model.3F/near/426331967
aa01623 to
2540070
Compare
|
@bors r+ |
Documents that
BikeshedIntrinsicFrommodels transmute-via-union, which is slightly more expressive than the transmute-via-cast implemented bytransmute_copy. Additionally, we provide an implementation of transmute-via-union as a method on theBikeshedIntrinsicFromtrait with additional documentation on the boundary between trait invariants and caller obligations.Whether or not transmute-via-union is the right kind of transmute to model remains up for discussion [1]. Regardless, it seems wise to document the present behavior.
[1] https://rust-lang.zulipchat.com/#narrow/stream/216762-project-safe-transmute/topic/What.20'kind'.20of.20transmute.20to.20model.3F/near/426331967
Tracking Issue: #99571
r? @compiler-errors
cc @scottmcm, @Lokathor