Skip to content

Commit 5fdf6b0

Browse files
committed
Un-feature-gate struct variants
1 parent 1f97923 commit 5fdf6b0

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

text/0000-struct-variants.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
- Start Date: 2014-10-25
2+
- RFC PR:
3+
- Rust Issue:
4+
5+
# Summary
6+
7+
Just like structs, variants can come in three forms - unit-like, tuple-like,
8+
or struct-like:
9+
```rust
10+
enum Foo {
11+
Foo,
12+
Bar(int, String),
13+
Baz { a: int, b: String }
14+
}
15+
```
16+
The last form is currently feature gated. This RFC proposes to remove that gate
17+
before 1.0.
18+
19+
# Motivation
20+
21+
Tuple variants with multiple fields can become difficult to work with,
22+
especially when the types of the fields don't make it obvious what each one is.
23+
It is not an uncommon sight in the compiler to see inline comments used to help
24+
identify the various variants of an enum, such as this snippet from
25+
`rustc::middle::def`:
26+
```rust
27+
pub enum Def {
28+
// ...
29+
DefVariant(ast::DefId /* enum */, ast::DefId /* variant */, bool /* is_structure */),
30+
DefTy(ast::DefId, bool /* is_enum */),
31+
// ...
32+
}
33+
```
34+
If these were changed to struct variants, this ad-hoc documentation would move
35+
into the names of the fields themselves. These names are visible in rustdoc,
36+
so a developer doesn't have to go source diving to figure out what's going on.
37+
In addition, the fields of struct variants can have documentation attached.
38+
```rust
39+
pub enum Def {
40+
// ...
41+
DefVariant {
42+
enum_did: ast::DefId,
43+
variant_did: ast::DefId,
44+
/// Identifies the variant as tuple-like or struct-like
45+
is_structure: bool,
46+
},
47+
DefTy {
48+
did: ast::DefId,
49+
is_enum: bool,
50+
},
51+
// ...
52+
}
53+
```
54+
55+
As the number of fields in a variant increases, it becomes increasingly crucial
56+
to use struct variants. For example, consider this snippet from
57+
`rust-postgres`:
58+
```rust
59+
enum FrontendMessage<'a> {
60+
// ...
61+
Bind {
62+
pub portal: &'a str,
63+
pub statement: &'a str,
64+
pub formats: &'a [i16],
65+
pub values: &'a [Option<Vec<u8>>],
66+
pub result_formats: &'a [i16]
67+
},
68+
// ...
69+
}
70+
```
71+
If we convert `Bind` to a tuple variant:
72+
```rust
73+
enum FrontendMessage<'a> {
74+
// ...
75+
Bind(&'a str, &'a str, &'a [i16], &'a [Option<Vec<u8>>], &'a [i16]),
76+
// ...
77+
}
78+
```
79+
we run into both the documentation issues discussed above, as well as ergonomic
80+
issues. If code only cares about the `values` and `formats` fields, working
81+
with a struct variant is nicer:
82+
```rust
83+
match msg {
84+
// you can reorder too!
85+
Bind { values, formats, .. } => ...
86+
// ...
87+
}
88+
```
89+
versus
90+
```rust
91+
match msg {
92+
Bind(_, _, formats, values, _) => ...
93+
// ...
94+
}
95+
```
96+
97+
This feature gate was originally put in place because there were many serious
98+
bugs in the compiler's support for struct variants. This is not the case today.
99+
The issue tracker does not appear have any open correctness issues related to
100+
struct variants and many libraries, including rustc itself, have been using
101+
them without trouble for a while.
102+
103+
# Detailed design
104+
105+
Change the `Status` of the `struct_variant` feature from `Active` to
106+
`Accepted`.
107+
108+
# Drawbacks
109+
110+
Adding formal support for a feature increases the maintenance burden of rustc.
111+
112+
# Alternatives
113+
114+
If struct variants remain feature gated at 1.0, libraries that want to ensure
115+
that they will continue working into the future will be forced to avoid struct
116+
variants since there are no guarantees about backwards compatibility of
117+
feature-gated parts of the language.
118+
119+
# Unresolved questions
120+
121+
N/A

0 commit comments

Comments
 (0)