Skip to content

make transparent enums more ordinary - #67323

Merged
bors merged 1 commit into
rust-lang:masterfrom
Centril:tes
Dec 16, 2019
Merged

make transparent enums more ordinary#67323
bors merged 1 commit into
rust-lang:masterfrom
Centril:tes

Conversation

@Centril

Copy link
Copy Markdown
Contributor

By recognizing that structs & unions have one variant, we can make the treatment of transparent enums less ad-hoc.

cc #60405

r? @davidtwco

@rust-highfiverust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 15, 2019
@davidtwco

Copy link
Copy Markdown
Member

@bors r+ rollup

@bors

bors commented Dec 16, 2019

Copy link
Copy Markdown
Collaborator

📌 Commit 5d73af2 has been approved by davidtwco

@bors

bors commented Dec 16, 2019

Copy link
Copy Markdown
Collaborator

🌲 The tree is currently closed for pull requests below priority 100, this pull request will be tested once the tree is reopened

@borsbors 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 Dec 16, 2019
Centril added a commit to Centril/rust that referenced this pull request Dec 16, 2019
make transparent enums more ordinary
By recognizing that structs & unions have one variant, we can make the treatment of transparent enums less ad-hoc.
cc rust-lang#60405
r? @davidtwco
@CentrilCentril mentioned this pull request Dec 16, 2019
Centril added a commit to Centril/rust that referenced this pull request Dec 16, 2019
make transparent enums more ordinary
By recognizing that structs & unions have one variant, we can make the treatment of transparent enums less ad-hoc.
cc rust-lang#60405
r? @davidtwco
@CentrilCentril mentioned this pull request Dec 16, 2019
bors added a commit that referenced this pull request Dec 16, 2019
Rollup of 8 pull requests
Successful merges:
- #67249 (Improve code generated for `starts_with(<literal char>)`)
- #67308 (Delete flaky test net::tcp::tests::fast_rebind)
- #67318 (Improve typeck & lowering docs for slice patterns)
- #67322 (use Self alias in place of macros)
- #67323 (make transparent enums more ordinary)
- #67336 (Fix JS error when loading page with search)
- #67344 (.gitignore: Don't ignore a file that exists in the repository)
- #67349 (Minor: update Unsize docs for dyn syntax)
Failed merges:
r? @ghost
@bors
bors merged commit 5d73af2 into rust-lang:masterDec 16, 2019
@Centril
Centril deleted the tes branch December 17, 2019 05:44
bors added a commit that referenced this pull request Jan 27, 2020
…enkov
Stabilize `#[repr(transparent)]` on `enum`s in Rust 1.42.0
# Stabilization report
The following is the stabilization report for `#![feature(transparent_enums)]`.
Tracking issue: #60405
[Version target](https://forge.rust-lang.org/#current-release-versions): 1.42 (2020-01-30 => beta, 2020-03-12 => stable).
## User guide
A `struct` with only a single non-ZST field (let's call it `foo`) can be marked as `#[repr(transparent)]`. Such a `struct` has the same layout and ABI as `foo`. Here, we also extend this ability to `enum`s with only one variant, subject to the same restrictions as for the equivalent `struct`. That is, you can now write:
```rust
#[repr(transparent)]
enum Foo { Bar(u8) }
```
which, in terms of layout and ABI, is equivalent to:
```rust
#[repr(transparent)]
struct Foo(u8);
```
## Motivation
This is not a major feature that will unlock new and important use-cases. The utility of `repr(transparent)` `enum`s is indeed limited. However, there is still some value in it:
1. It provides conceptual simplification of the language in terms of treating univariant `enum`s and `struct`s the same, as both are product types. Indeed, languages like Haskell only have `data` as the only way to construct user-defined ADTs in the language.
2. In rare occasions, it might be that the user started out with a univariant `enum` for whatever reason (e.g. they thought they might extend it later). Now they want to make this `enum` `transparent` without breaking users by turning it into a `struct`. By lifting the restriction here, now they can.
## Technical specification
The reference specifies [`repr(transparent)` on a `struct`](https://doc.rust-lang.org/nightly/reference/type-layout.html#the-transparent-representation) as:
> ### The transparent Representation
>
> The `transparent` representation can only be used on `struct`s that have:
> - a single field with non-zero size, and
> - any number of fields with size 0 and alignment 1 (e.g. `PhantomData<T>`).
>
> Structs with this representation have the same layout and ABI as the single non-zero sized field.
>
> This is different than the `C` representation because a struct with the `C` representation will always have the ABI of a `C` `struct` while, for example, a struct with the `transparent` representation with a primitive field will have the ABI of the primitive field.
>
> Because this representation delegates type layout to another type, it cannot be used with any other representation.
Here, we amend this to include univariant `enum`s as well with the same static restrictions and the same effects on dynamic semantics.
## Tests
All the relevant tests are adjusted in the PR diff but are recounted here:
- `src/test/ui/repr/repr-transparent.rs` checks that `repr(transparent)` on an `enum` must be univariant, rather than having zero or more than one variant. Restrictions on the fields inside the only variants, like for those on `struct`s, are also checked here.
- A number of codegen tests are provided as well:
- `src/test/codegen/repr-transparent.rs` (the canonical test)
- `src/test/codegen/repr-transparent-aggregates-1.rs`
- `src/test/codegen/repr-transparent-aggregates-2.rs`
- `src/test/codegen/repr-transparent-aggregates-3.rs`
- `src/test/ui/lint/lint-ctypes-enum.rs` tests the interactions with the `improper_ctypes` lint.
## History
- 2019-04-30, RFC rust-lang/rfcs#2645
Author: @mjbshaw
Reviewers: The Language Team
This is the RFC that proposes allowing `#[repr(transparent)]` on `enum`s and `union`.
- 2019-06-11, PR #60463
Author: @mjbshaw
Reviewers: @varkor and @rkruppe
The PR implements the RFC aforementioned in full.
- 2019, PR #67323
Author: @Centril
Reviewers: @davidtwco
The PR reorganizes the static checks taking advantage of the fact that `struct`s and `union`s are internally represented as ADTs with a single variant.
- This PR stabilizes `transparent_enums`.
## Related / possible future work
The remaining work here is to figure out the semantics of `#[repr(transparent)]` on `union`s and stabilize those. This work continues to be tracked in #60405.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@Centril@davidtwco@bors@rust-highfive