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

Make MaybeUninit #[repr(transparent)] #61802

Merged
merged 1 commit into from
Jun 19, 2019

Conversation

mjbshaw
Copy link
Contributor

@mjbshaw mjbshaw commented Jun 13, 2019

Tracking issue: #60405

@rust-highfive
Copy link
Collaborator

r? @dtolnay

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 13, 2019
@mjbshaw
Copy link
Contributor Author

mjbshaw commented Jun 13, 2019

cc @Centril @RalfJung

@Centril Centril added I-nominated T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Jun 13, 2019
@Centril
Copy link
Contributor

Centril commented Jun 13, 2019

r? @cramertj

@rust-highfive rust-highfive assigned cramertj and unassigned dtolnay Jun 13, 2019
@cramertj
Copy link
Member

We discussed this in the lang team meeting today, and the conclusion was that we'd like to document and guarantee that MaybeUninit<T> share's T's size, alignment, and ABI when being passed directly by-value (not necessarily as a member of another type).

It's unclear exactly what we might want #[repr(transparent)] to mean on unions, or if we should even allow it. All existing uses of #[repr(transparent)} also grant that e.g. Option<Wrapper<T>> has the same representation as Option<T>, but this is not true for #[repr(transparent)] unions, and cannot be true. With that in mind, we'd like to note that MaybeUninit<T> is not guaranteed to be #[repr(transparent)], but only the three above properties (size, align, direct by-value ABI).

Implementation wise, this works out to exactly what this PR does-- sticking #[repr(transparent)] on the type, so I think we're all okay with merging this so long as we document it appropriately.

@cramertj cramertj added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed I-nominated S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 13, 2019
@hanna-kruppe
Copy link
Contributor

hanna-kruppe commented Jun 13, 2019

It's unclear exactly what we might want #[repr(transparent)] to mean on unions, or if we should even allow it. All existing uses of #[repr(transparent)} also grant that e.g. Option<Wrapper<T>> has the same representation as Option<T>, but this is not true for #[repr(transparent)] unions, and cannot be true. With that in mind, we'd like to note that MaybeUninit<T> is not guaranteed to be #[repr(transparent)], but only the three above properties (size, align, direct by-value ABI).

So, uh, this sounds like y'all don't want RFC 2645 after all. Not that I disagree, but I'm surprised to hear this so soon after the RFC was merged, especially since this exact concern was brough up and marked resolved during the FCP. Or do I misunderstand?

Implementation wise, this works out to exactly what this PR does-- sticking #[repr(transparent)] on the type, so I think we're all okay with merging this so long as we document it appropriately.

Note that the repr(transparent) attribute is shown in rustdoc, so this is not just an implementation concern. More generally, one argument in favor of the RFC was that having this general, "public" attribute would be a cleaner way for (programmers, docs, tools, etc.) to learn about the size/align/by-value-ABI transparency vs just stating those guarantees in prose as one-off properties of MaybeUninit. If we end up making MaybeUninit special anyway, the rationale for transparent unions is even weaker than it IMO already way.

@Centril
Copy link
Contributor

Centril commented Jun 13, 2019

So, uh, this sounds like y'all don't want RFC 2645 after all. Not that I disagree, but I'm surprised to hear this so soon after the RFC was merged, especially since this exact concern was brough up and marked resolved during the FCP. Or do I misunderstand?

I still want the RFC and to affirm the guarantee through an attribute eventually.

If we end up making MaybeUninit special anyway, the rationale for transparent unions is even weaker than it IMO already way.

Our discussions was mostly around landing this PR before we stabilize the attribute itself, which I do think we should eventually.

@cramertj
Copy link
Member

@rkruppe yeah to be clear, I don't think we're going back on what we said in that RFC, only saying that we don't want this particular addition to be a de-facto stabilization of that RFC's behavior.

@hanna-kruppe
Copy link
Contributor

Thanks for the clarification. I would like some further clarification on one point: was this decision made aware of the fact that repr(transparent) is shown on the type in rustdoc? I, personally, do worry that this makes adding the attribute a de-facto stabilization of transparent unions as a concept, and by extension (since the surprise around Option is fundamental and everything else is dead obvious) the semantics currently given to them.

@Centril
Copy link
Contributor

Centril commented Jun 13, 2019

@rkruppe

was this decision made aware of the fact that repr(transparent) is shown on the type in rustdoc?

I don't believe this fact was brought up in the discussions.

@RalfJung
Copy link
Member

Implementation wise, this works out to exactly what this PR does

Notice that this PR is effectively a NOP -- repr(transparent) does not actually change how we compute layout, it just adds some extra checks that ensure that we end up in the "happy path".

@mjbshaw
Copy link
Contributor Author

mjbshaw commented Jun 18, 2019

I have revised the documentation on MaybeUninit that hopefully addresses some of the concerns here. If it is insufficient or requires more work, let me know.

@cramertj
Copy link
Member

Nice!

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Jun 18, 2019

📌 Commit 0f9dc6c has been approved by cramertj

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 18, 2019
///
/// While `MaybeUninit` is `#[repr(transparent)]` (indicating it guarantees the same size,
/// alignment, and ABI as `T`), this does *not* change any of the previous caveats. `Option<T>` and
/// `Option<MaybeUninit<T>>` may still have different sizes, and types containing a field of type
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is odd. We just said two paragraphs earlier that this is the case, why repeat it here?

I think it makes more sense to change the previous paragraph (starting "However remember that a type containing a MaybeUninit<T>") to say something like "Despite being repr(transparent), ..."

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mjbshaw can you file a follow-up PR to improve the wording here or should I do that?

Centril added a commit to Centril/rust that referenced this pull request Jun 18, 2019
…=cramertj

Make MaybeUninit #[repr(transparent)]

Tracking issue: rust-lang#60405
Centril added a commit to Centril/rust that referenced this pull request Jun 18, 2019
…=cramertj

Make MaybeUninit #[repr(transparent)]

Tracking issue: rust-lang#60405
bors added a commit that referenced this pull request Jun 19, 2019
Rollup of 11 pull requests

Successful merges:

 - #61505 (Only show methods that appear in `impl` blocks in the Implementors sections of trait doc pages)
 - #61701 (move stray run-pass const tests into const/ folder)
 - #61748 (Tweak transparent enums and unions diagnostic spans)
 - #61802 (Make MaybeUninit #[repr(transparent)])
 - #61839 (ci: Add a script for generating CPU usage graphs)
 - #61842 (Remove unnecessary lift calls)
 - #61843 (Turn down the myriad-closures test)
 - #61896 (rustc_typeck: correctly compute `Substs` for `Res::SelfCtor`.)
 - #61898 (syntax: Factor out common fields from `SyntaxExtension` variants)
 - #61938 (create an issue for miri even in status test-fail)
 - #61941 (Preserve generator and yield source for error messages)

Failed merges:

r? @ghost
bors added a commit that referenced this pull request Jun 19, 2019
Rollup of 11 pull requests

Successful merges:

 - #61505 (Only show methods that appear in `impl` blocks in the Implementors sections of trait doc pages)
 - #61701 (move stray run-pass const tests into const/ folder)
 - #61748 (Tweak transparent enums and unions diagnostic spans)
 - #61802 (Make MaybeUninit #[repr(transparent)])
 - #61839 (ci: Add a script for generating CPU usage graphs)
 - #61842 (Remove unnecessary lift calls)
 - #61843 (Turn down the myriad-closures test)
 - #61896 (rustc_typeck: correctly compute `Substs` for `Res::SelfCtor`.)
 - #61898 (syntax: Factor out common fields from `SyntaxExtension` variants)
 - #61938 (create an issue for miri even in status test-fail)
 - #61941 (Preserve generator and yield source for error messages)

Failed merges:

r? @ghost
bors added a commit that referenced this pull request Jun 19, 2019
Rollup of 11 pull requests

Successful merges:

 - #61505 (Only show methods that appear in `impl` blocks in the Implementors sections of trait doc pages)
 - #61701 (move stray run-pass const tests into const/ folder)
 - #61748 (Tweak transparent enums and unions diagnostic spans)
 - #61802 (Make MaybeUninit #[repr(transparent)])
 - #61839 (ci: Add a script for generating CPU usage graphs)
 - #61842 (Remove unnecessary lift calls)
 - #61843 (Turn down the myriad-closures test)
 - #61896 (rustc_typeck: correctly compute `Substs` for `Res::SelfCtor`.)
 - #61898 (syntax: Factor out common fields from `SyntaxExtension` variants)
 - #61938 (create an issue for miri even in status test-fail)
 - #61941 (Preserve generator and yield source for error messages)

Failed merges:

r? @ghost
@bors bors merged commit 0f9dc6c into rust-lang:master Jun 19, 2019
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Aug 29, 2019
Pkgsrc changes:
 * Add a patch to llvm to deal with const dli_saddr.
 * Adapt two other patches.
 * Cross-build currently fails, so i386, powerpc and sparc64 bootstrap
   kits for 1.37.0 are built natively.  Missing aarch64 hardware, so that's
   not available yet.
 * Bump bootstrap requirements to 1.36.0 except for armv7-unknown-netbsd-eabihf
   which I've not managed to cross-build.

Upstream changes:

Version 1.37.0 (2019-08-15)
==========================

Language
--------
- `#[must_use]` will now warn if the type is contained in a [tuple][61100],
  [`Box`][62228], or an [array][62235] and unused.
- [You can now use the `cfg` and `cfg_attr` attributes on
  generic parameters.][61547]
- [You can now use enum variants through type alias.][61682] e.g. You can
  write the following:
  ```rust
  type MyOption = Option<u8>;

  fn increment_or_zero(x: MyOption) -> u8 {
      match x {
          MyOption::Some(y) => y + 1,
          MyOption::None => 0,
      }
  }
  ```
- [You can now use `_` as an identifier for consts.][61347] e.g. You can write
  `const _: u32 = 5;`.
- [You can now use `#[repr(align(X)]` on enums.][61229]
- [The  `?`/_"Kleene"_ macro operator is now available in the
  2015 edition.][60932]

Compiler
--------
- [You can now enable Profile-Guided Optimization with the `-C profile-generate`
  and `-C profile-use` flags.][61268] For more information on how to use profile
  guided optimization, please refer to the [rustc book][rustc-book-pgo].
- [The `rust-lldb` wrapper script should now work again.][61827]

Libraries
---------
- [`mem::MaybeUninit<T>` is now ABI-compatible with `T`.][61802]

Stabilized APIs
---------------
- [`BufReader::buffer`]
- [`BufWriter::buffer`]
- [`Cell::from_mut`]
- [`Cell<[T]>::as_slice_of_cells`][`Cell<slice>::as_slice_of_cells`]
- [`DoubleEndedIterator::nth_back`]
- [`Option::xor`]
- [`Wrapping::reverse_bits`]
- [`i128::reverse_bits`]
- [`i16::reverse_bits`]
- [`i32::reverse_bits`]
- [`i64::reverse_bits`]
- [`i8::reverse_bits`]
- [`isize::reverse_bits`]
- [`slice::copy_within`]
- [`u128::reverse_bits`]
- [`u16::reverse_bits`]
- [`u32::reverse_bits`]
- [`u64::reverse_bits`]
- [`u8::reverse_bits`]
- [`usize::reverse_bits`]

Cargo
-----
- [`Cargo.lock` files are now included by default when publishing executable crates
  with executables.][cargo/7026]
- [You can now specify `default-run="foo"` in `[package]` to specify the
  default executable to use for `cargo run`.][cargo/7056]

Misc
----

Compatibility Notes
-------------------
- [Using `...` for inclusive range patterns will now warn by default.][61342]
  Please transition your code to using the `..=` syntax for inclusive
  ranges instead.
- [Using a trait object without the `dyn` will now warn by default.][61203]
  Please transition your code to use `dyn Trait` for trait objects instead.

[62228]: rust-lang/rust#62228
[62235]: rust-lang/rust#62235
[61802]: rust-lang/rust#61802
[61827]: rust-lang/rust#61827
[61547]: rust-lang/rust#61547
[61682]: rust-lang/rust#61682
[61268]: rust-lang/rust#61268
[61342]: rust-lang/rust#61342
[61347]: rust-lang/rust#61347
[61100]: rust-lang/rust#61100
[61203]: rust-lang/rust#61203
[61229]: rust-lang/rust#61229
[60932]: rust-lang/rust#60932
[cargo/7026]: rust-lang/cargo#7026
[cargo/7056]: rust-lang/cargo#7056
[`BufReader::buffer`]: https://doc.rust-lang.org/std/io/struct.BufReader.html#method.buffer
[`BufWriter::buffer`]: https://doc.rust-lang.org/std/io/struct.BufWriter.html#method.buffer
[`Cell::from_mut`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.from_mut
[`Cell<slice>::as_slice_of_cells`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.as_slice_of_cells
[`DoubleEndedIterator::nth_back`]: https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html#method.nth_back
[`Option::xor`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.xor
[`RefCell::try_borrow_unguarded`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.try_borrow_unguarded
[`Wrapping::reverse_bits`]: https://doc.rust-lang.org/std/num/struct.Wrapping.html#method.reverse_bits
[`i128::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i128.html#method.reverse_bits
[`i16::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i16.html#method.reverse_bits
[`i32::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i32.html#method.reverse_bits
[`i64::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i64.html#method.reverse_bits
[`i8::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i8.html#method.reverse_bits
[`isize::reverse_bits`]: https://doc.rust-lang.org/std/primitive.isize.html#method.reverse_bits
[`slice::copy_within`]: https://doc.rust-lang.org/std/primitive.slice.html#method.copy_within
[`u128::reverse_bits`]: https://doc.rust-lang.org/std/primitive.u128.html#method.reverse_bits
[`u16::reverse_bits`]: https://doc.rust-lang.org/std/primitive.u16.html#method.reverse_bits
[`u32::reverse_bits`]: https://doc.rust-lang.org/std/primitive.u32.html#method.reverse_bits
[`u64::reverse_bits`]: https://doc.rust-lang.org/std/primitive.u64.html#method.reverse_bits
[`u8::reverse_bits`]: https://doc.rust-lang.org/std/primitive.u8.html#method.reverse_bits
[`usize::reverse_bits`]: https://doc.rust-lang.org/std/primitive.usize.html#method.reverse_bits
[rustc-book-pgo]: https://doc.rust-lang.org/rustc/profile-guided-optimization.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants