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

stabilize union with 'ManuallyDrop' fields and 'impl Drop for Union' #77547

Merged
merged 2 commits into from
Oct 16, 2020

Conversation

RalfJung
Copy link
Member

@RalfJung RalfJung commented Oct 4, 2020

As discussed by @SimonSapin and @withoutboats, this PR proposes to stabilize parts of the untagged_union feature gate:

  • It will be possible to have a union with field type ManuallyDrop<T> for any T.
  • While at it I propose we also stabilize impl Drop for Union; to my knowledge, there are no open concerns around this feature.

In the RFC discussion, we also talked about allowing &mut T as another non-Copy non-dropping type, but that felt to me like an overly specific exception so I figured we'd wait if there is actually any use for such a special case.

Some things remain unstable and still require the untagged_union feature gate:

  • Union with fields that do not drop, are not Copy, and are not ManuallyDrop<_>. The reason to not stabilize this is to avoid semver concerns around libraries adding Drop implementations later. (This is already not fully semver compatible as, to my knowledge, the borrow checker will exploit the non-dropping nature of any type, but it seems prudent to avoid further increasing the amount of trouble adding an impl Drop can cause.)

Due to this, quite a few tests still need the untagged_union feature, but I think the ones where I could remove the feature flag provide good test coverage for the stable part.

Cc @rust-lang/lang

@rust-highfive
Copy link
Collaborator

r? @matthewjasper

(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 Oct 4, 2020
@RalfJung RalfJung added F-untagged_unions `#![feature(untagged_unions)]` I-nominated T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Oct 4, 2020
@jonas-schievink jonas-schievink added the relnotes Marks issues that should be documented in the release notes of the next release. label Oct 4, 2020
@RalfJung RalfJung force-pushed the stable-union-drop branch 2 times, most recently from 76ade65 to 4b42d43 Compare October 4, 2020 21:58
@scottmcm
Copy link
Member

scottmcm commented Oct 5, 2020

We've had enumsunions of Copy types stable for a while, but non-Copy was an open question largely about the potential non-obviousness about drop glue not happening. This proposes to sidestep that question by allowing ManuallyDrop<T> in unions for all Ts, since that way people visibly opt-in to the leaking behaviour. And that's also safe, so creating a union remains safe, even if that union has a non-drop type in it (via ManuallyDrop).

This also proposes allowing Drop implementations on union types, which seems hard to me to actually use, but I don't really have a problem with allowing if someone can find a way that they'd care.

See the OP here for more details.

@rfcbot fcp merge

--

@RalfJung Would this also be enough to remove #![feature(untagged_unions)] from at least core and std? I did a quick rg and everything looked like it's either using Copy types or is already doing ManuallyDrop.

@rfcbot
Copy link

rfcbot commented Oct 5, 2020

Team member @scottmcm has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Oct 5, 2020
@RalfJung
Copy link
Member Author

RalfJung commented Oct 5, 2020

We've had enums of Copy types stable for a while

s/enums/unions/

Would this also be enough to remove #![feature(untagged_unions)] from at least core and std? I did a quick rg and everything looked like it's either using Copy types or is already doing ManuallyDrop.

Good point, done -- except for the one in stdarch.

@rfcbot rfcbot added the final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. label Oct 5, 2020
@rfcbot
Copy link

rfcbot commented Oct 5, 2020

🔔 This is now entering its final comment period, as per the review above. 🔔

@rfcbot rfcbot removed the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Oct 5, 2020
@rfcbot rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. to-announce Announce this issue on triage meeting and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Oct 15, 2020
@rfcbot
Copy link

rfcbot commented Oct 15, 2020

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

The RFC will be merged soon.

@bors

This comment has been minimized.

@bors
Copy link
Contributor

bors commented Oct 16, 2020

📌 Commit defcd7f has been approved by matthewjasper

@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-review Status: Awaiting review from the assignee but also interested parties. labels Oct 16, 2020
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Oct 16, 2020
…ewjasper

stabilize union with 'ManuallyDrop' fields and 'impl Drop for Union'

As [discussed by @SimonSapin and @withoutboats](rust-lang#55149 (comment)), this PR proposes to stabilize parts of the `untagged_union` feature gate:

* It will be possible to have a union with field type `ManuallyDrop<T>` for any `T`.
* While at it I propose we also stabilize `impl Drop for Union`; to my knowledge, there are no open concerns around this feature.

In the RFC discussion, we also talked about allowing `&mut T` as another non-`Copy` non-dropping type, but that felt to me like an overly specific exception so I figured we'd wait if there is actually any use for such a special case.

Some things remain unstable and still require the `untagged_union` feature gate:
* Union with fields that do not drop, are not `Copy`, and are not `ManuallyDrop<_>`. The reason to not stabilize this is to avoid semver concerns around libraries adding `Drop` implementations later. (This is already not fully semver compatible as, to my knowledge, the borrow checker will exploit the non-dropping nature of any type, but it seems prudent to avoid further increasing the amount of trouble adding an `impl Drop` can cause.)

Due to this, quite a few tests still need the `untagged_union` feature, but I think the ones where I could remove the feature flag provide good test coverage for the stable part.

Cc @rust-lang/lang
JohnTitor added a commit to JohnTitor/rust that referenced this pull request Oct 16, 2020
…ewjasper

stabilize union with 'ManuallyDrop' fields and 'impl Drop for Union'

As [discussed by @SimonSapin and @withoutboats](rust-lang#55149 (comment)), this PR proposes to stabilize parts of the `untagged_union` feature gate:

* It will be possible to have a union with field type `ManuallyDrop<T>` for any `T`.
* While at it I propose we also stabilize `impl Drop for Union`; to my knowledge, there are no open concerns around this feature.

In the RFC discussion, we also talked about allowing `&mut T` as another non-`Copy` non-dropping type, but that felt to me like an overly specific exception so I figured we'd wait if there is actually any use for such a special case.

Some things remain unstable and still require the `untagged_union` feature gate:
* Union with fields that do not drop, are not `Copy`, and are not `ManuallyDrop<_>`. The reason to not stabilize this is to avoid semver concerns around libraries adding `Drop` implementations later. (This is already not fully semver compatible as, to my knowledge, the borrow checker will exploit the non-dropping nature of any type, but it seems prudent to avoid further increasing the amount of trouble adding an `impl Drop` can cause.)

Due to this, quite a few tests still need the `untagged_union` feature, but I think the ones where I could remove the feature flag provide good test coverage for the stable part.

Cc @rust-lang/lang
bors added a commit to rust-lang-ci/rust that referenced this pull request Oct 16, 2020
Rollup of 10 pull requests

Successful merges:

 - rust-lang#75209 (Suggest imports of unresolved macros)
 - rust-lang#77547 (stabilize union with 'ManuallyDrop' fields and 'impl Drop for Union')
 - rust-lang#77827 (Don't link to nightly primitives on stable channel)
 - rust-lang#77855 (resolve: further improvements to "try using the enum's variant" diagnostic)
 - rust-lang#77900 (Use fdatasync for File::sync_data on more OSes)
 - rust-lang#77925 (Suggest minimal subset features in `incomplete_features` lint)
 - rust-lang#77971 (Deny broken intra-doc links in linkchecker)
 - rust-lang#77991 (Bump backtrace-rs)
 - rust-lang#77992 (instrument-coverage: try our best to not ICE)
 - rust-lang#78013 (Fix sidebar scroll on mobile devices)

Failed merges:

r? `@ghost`
@bors bors merged commit 3356ad7 into rust-lang:master Oct 16, 2020
@rustbot rustbot added this to the 1.49.0 milestone Oct 16, 2020
@RalfJung RalfJung deleted the stable-union-drop branch October 16, 2020 23:23
@ehuss
Copy link
Contributor

ehuss commented Oct 18, 2020

@RalfJung Should this be documented in the reference? It doesn't appear to mention the Copy restriction (and, confusingly, it seems to imply that non-Copy fields can be used with unsafe).

@RalfJung
Copy link
Member Author

@ehuss I suppose yes this should be documented -- I am not very fimiliar with how the reference is maintained.

@RalfJung
Copy link
Member Author

confusingly, it seems to imply that non-Copy fields can be used with unsafe).

No, it says that writing to Copy fields is safe.

Since transmutes can cause unexpected or undefined behaviour, unsafe is
required to read from a union field or to write to a field that doesn't
implement [Copy]

@RalfJung
Copy link
Member Author

However, that seems unnecessary for ManuallyDrop fields... I should probably submit a PR to make their assignment safe as well.

@spastorino spastorino removed the to-announce Announce this issue on triage meeting label Oct 22, 2020
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 15, 2020
…sakis

consider assignments of union field of ManuallyDrop type safe

Assigning to `Copy` union fields is safe because that assignment will never drop anything. However, with rust-lang#77547, unions may also have `ManuallyDrop` fields, and their assignments are currently still unsafe. That seems unnecessary though, as assigning `ManuallyDrop` does not drop anything either, and is thus safe even for union fields.

I assume this will at least require FCP.
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Feb 14, 2021
Pkgsrc changes:
 * Adjust patches, convert tabs to spaces so that tests pass.
 * Remove patches which are no longer needed (upstream changed)
 * Minor adjustments for SunOS, e.g. disable stack probes.
 * Adjust cargo checksum patching accordingly.
 * Remove commented-out use of PATCHELF on NetBSD, which doesn't work anyway...

Upstream changes:

Version 1.49.0 (2020-12-31)
============================

Language
-----------------------

- [Unions can now implement `Drop`, and you can now have a field in a union
  with `ManuallyDrop<T>`.][77547]
- [You can now cast uninhabited enums to integers.][76199]
- [You can now bind by reference and by move in patterns.][76119] This
  allows you to selectively borrow individual components of a type. E.g.
  ```rust
  #[derive(Debug)]
  struct Person {
      name: String,
      age: u8,
  }

  let person = Person {
      name: String::from("Alice"),
      age: 20,
  };

  // `name` is moved out of person, but `age` is referenced.
  let Person { name, ref age } = person;
  println!("{} {}", name, age);
  ```

Compiler
-----------------------

- [Added tier 1\* support for `aarch64-unknown-linux-gnu`.][78228]
- [Added tier 2 support for `aarch64-apple-darwin`.][75991]
- [Added tier 2 support for `aarch64-pc-windows-msvc`.][75914]
- [Added tier 3 support for `mipsel-unknown-none`.][78676]
- [Raised the minimum supported LLVM version to LLVM 9.][78848]
- [Output from threads spawned in tests is now captured.][78227]
- [Change os and vendor values to "none" and "unknown" for some targets][78951]

\* Refer to Rust's [platform support page][forge-platform-support] for more
information on Rust's tiered platform support.

Libraries
-----------------------

- [`RangeInclusive` now checks for exhaustion when calling `contains`
  and indexing.][78109]
- [`ToString::to_string` now no longer shrinks the internal buffer
  in the default implementation.][77997]
- [`ops::{Index, IndexMut}` are now implemented for fixed sized
  arrays of any length.][74989]

Stabilized APIs
---------------

- [`slice::select_nth_unstable`]
- [`slice::select_nth_unstable_by`]
- [`slice::select_nth_unstable_by_key`]

The following previously stable methods are now `const`.

- [`Poll::is_ready`]
- [`Poll::is_pending`]

Cargo
-----------------------
- [Building a crate with `cargo-package` should now be independently
  reproducible.][cargo/8864]
- [`cargo-tree` now marks proc-macro crates.][cargo/8765]
- [Added `CARGO_PRIMARY_PACKAGE` build-time environment
  variable.]  [cargo/8758] This variable will be set if the crate
  being built is one the user selected to build, either with `-p`
  or through defaults.
- [You can now use glob patterns when specifying packages &
  targets.][cargo/8752]


Compatibility Notes
-------------------
- [Demoted `i686-unknown-freebsd` from host tier 2 to target tier
  2 support.][78746]
- [Macros that end with a semi-colon are now treated as statements
  even if they expand to nothing.][78376]
- [Rustc will now check for the validity of some built-in attributes
  on enum variants.][77015] Previously such invalid or unused
  attributes could be ignored.
- Leading whitespace is stripped more uniformly in documentation
  comments, which may change behavior. You read [this post about
  the changes][rustdoc-ws-post] for more details.
- [Trait bounds are no longer inferred for associated types.][79904]

Internal Only
-------------
These changes provide no direct user facing benefits, but represent
significant improvements to the internals and overall performance
of rustc and related tools.

- [rustc's internal crates are now compiled using the `initial-exec` Thread
  Local Storage model.][78201]
- [Calculate visibilities once in resolve.][78077]
- [Added `system` to the `llvm-libunwind` bootstrap config option.][77703]
- [Added `--color` for configuring terminal color support to bootstrap.][79004]


[75991]: rust-lang/rust#75991
[78951]: rust-lang/rust#78951
[78848]: rust-lang/rust#78848
[78746]: rust-lang/rust#78746
[78376]: rust-lang/rust#78376
[78228]: rust-lang/rust#78228
[78227]: rust-lang/rust#78227
[78201]: rust-lang/rust#78201
[78109]: rust-lang/rust#78109
[78077]: rust-lang/rust#78077
[77997]: rust-lang/rust#77997
[77703]: rust-lang/rust#77703
[77547]: rust-lang/rust#77547
[77015]: rust-lang/rust#77015
[76199]: rust-lang/rust#76199
[76119]: rust-lang/rust#76119
[75914]: rust-lang/rust#75914
[74989]: rust-lang/rust#74989
[79004]: rust-lang/rust#79004
[78676]: rust-lang/rust#78676
[79904]: rust-lang/rust#79904
[cargo/8864]: rust-lang/cargo#8864
[cargo/8765]: rust-lang/cargo#8765
[cargo/8758]: rust-lang/cargo#8758
[cargo/8752]: rust-lang/cargo#8752
[`slice::select_nth_unstable`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.select_nth_unstable
[`slice::select_nth_unstable_by`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.select_nth_unstable_by
[`slice::select_nth_unstable_by_key`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.select_nth_unstable_by_key
[`hint::spin_loop`]: https://doc.rust-lang.org/stable/std/hint/fn.spin_loop.html
[`Poll::is_ready`]: https://doc.rust-lang.org/stable/std/task/enum.Poll.html#method.is_ready
[`Poll::is_pending`]: https://doc.rust-lang.org/stable/std/task/enum.Poll.html#method.is_pending
[rustdoc-ws-post]: https://blog.guillaume-gomez.fr/articles/2020-11-11+New+doc+comment+handling+in+rustdoc
yvt added a commit to r3-os/r3 that referenced this pull request Aug 13, 2022
Unions with `impl Copy` and `ManuallyDrop` fields have been stabilized
by [rust-lang/rust#77547][1] back in 2020, making enabling the feature
already unnecessary for us. A few more field types have been added to
the allowlist later by [rust-lang/rust#97995][2], which also removed the
feature as there was no intent to stabilize more field types.

[1]: rust-lang/rust#77547
[2]: rust-lang/rust#97995
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. F-untagged_unions `#![feature(untagged_unions)]` finished-final-comment-period The final comment period is finished for this PR / Issue. relnotes Marks issues that should be documented in the release notes of the next release. 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.

10 participants