-
Notifications
You must be signed in to change notification settings - Fork 13.3k
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 ofDst
are 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
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+ |
…er-errors Document & implement the transmutation modeled by `BikeshedIntrinsicFrom` 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 Tracking Issue: rust-lang#99571 r? `@compiler-errors` cc `@scottmcm,` `@Lokathor`
…iaskrgr Rollup of 9 pull requests Successful merges: - rust-lang#126013 (Add `#[warn(unreachable_pub)]` to a bunch of compiler crates) - rust-lang#128157 (deduplicate and clarify rules for converting pointers to references) - rust-lang#129032 (Document & implement the transmutation modeled by `BikeshedIntrinsicFrom`) - rust-lang#129250 (Do not ICE on non-ADT rcvr type when looking for crate version collision) - rust-lang#129340 (Remove Duplicate E0381 Label) - rust-lang#129560 ([rustdoc] Generate source link on impl associated types) - rust-lang#129622 (Remove a couple of unused feature enables) - rust-lang#129625 (Rename `ParenthesizedGenericArgs` to `GenericArgsMode`) - rust-lang#129626 (Remove `ParamMode::ExplicitNamed`) Failed merges: - rust-lang#128166 (Improved `checked_isqrt` and `isqrt` methods) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#129032 - jswrenn:transmute-method, r=compiler-errors Document & implement the transmutation modeled by `BikeshedIntrinsicFrom` 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 Tracking Issue: rust-lang#99571 r? `@compiler-errors` cc `@scottmcm,` `@Lokathor`
Documents that
BikeshedIntrinsicFrom
models 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 theBikeshedIntrinsicFrom
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
Tracking Issue: #99571
r? @compiler-errors
cc @scottmcm, @Lokathor