Skip to content

Commit c351aa7

Browse files
committed
Clarify exactly which kinds of enums can be as casted.
The field-less casting was grandfathered in when arbitrary_enum_discriminant was stabilized. It probably shouldn't be allowed.
1 parent 5d9300c commit c351aa7

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

src/expressions/operator-expr.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ reference types and `mut` or `const` in pointer types.
368368
| Type of `e` | `U` | Cast performed by `e as U` |
369369
|-----------------------|-----------------------|----------------------------------|
370370
| Integer or Float type | Integer or Float type | Numeric cast |
371-
| [Unit-only enum] | Integer type | Enum cast |
371+
| Enumeration | Integer type | Enum cast |
372372
| `bool` or `char` | Integer type | Primitive to integer cast |
373373
| `u8` | `char` | `u8` to `char` cast |
374374
| `*T` | `*V` where `V: Sized` \* | Pointer to pointer cast |
@@ -430,6 +430,10 @@ halfway between two floating point numbers.
430430
#### Enum cast
431431

432432
Casts an enum to its discriminant, then uses a numeric cast if needed.
433+
Casting is limited to the following kinds of enumerations:
434+
435+
* [Unit-only enums]
436+
* [Field-less enums] without [explicit discriminants], or where only unit-variants have explicit discriminants
433437

434438
#### Primitive to integer cast
435439

@@ -632,6 +636,8 @@ See [this test] for an example of using this dependency.
632636

633637
[copies or moves]: ../expressions.md#moved-and-copied-types
634638
[dropping]: ../destructors.md
639+
[explicit discriminants]: ../items/enumerations.md#explicit-discriminants
640+
[field-less enums]: ../items/enumerations.md#field-less-enum
635641
[grouped expression]: grouped-expr.md
636642
[literal expression]: literal-expr.md#integer-literal-expressions
637643
[logical and]: ../types/boolean.md#logical-and
@@ -643,7 +649,7 @@ See [this test] for an example of using this dependency.
643649
[assignee expression]: ../expressions.md#place-expressions-and-value-expressions
644650
[undefined behavior]: ../behavior-considered-undefined.md
645651
[unit]: ../types/tuple.md
646-
[Unit-only enum]: ../items/enumerations.md#unit-only-enum
652+
[Unit-only enums]: ../items/enumerations.md#unit-only-enum
647653
[value expression]: ../expressions.md#place-expressions-and-value-expressions
648654
[temporary value]: ../expressions.md#temporaries
649655
[this test]: https://github.com/rust-lang/rust/blob/1.58.0/src/test/ui/expr/compound-assignment/eval-order.rs

src/items/enumerations.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,35 @@ assert_eq!(1, Enum::Bar as isize);
192192
assert_eq!(2, Enum::Baz as isize);
193193
```
194194

195+
[Field-less enums] can be casted if they do not have explicit discriminants, or where only unit variants are explicit.
196+
197+
```rust
198+
enum Fieldless {
199+
Tuple(),
200+
Struct{},
201+
Unit,
202+
}
203+
204+
assert_eq!(0, Fieldless::Tuple() as isize);
205+
assert_eq!(1, Fieldless::Struct{} as isize);
206+
assert_eq!(2, Fieldless::Unit as isize);
207+
208+
#[repr(u8)]
209+
enum FieldlessWithDiscrimants {
210+
First = 10,
211+
Tuple(),
212+
Second = 20,
213+
Struct{},
214+
Unit,
215+
}
216+
217+
assert_eq!(10, FieldlessWithDiscrimants::First as u8);
218+
assert_eq!(11, FieldlessWithDiscrimants::Tuple() as u8);
219+
assert_eq!(20, FieldlessWithDiscrimants::Second as u8);
220+
assert_eq!(21, FieldlessWithDiscrimants::Struct{} as u8);
221+
assert_eq!(22, FieldlessWithDiscrimants::Unit as u8);
222+
```
223+
195224
#### Pointer Casting
196225

197226
If the enumeration specifies a [primitive representation], then the
@@ -285,3 +314,4 @@ enum E {
285314
[default representation]: ../type-layout.md#the-default-representation
286315
[primitive representation]: ../type-layout.md#primitive-representations
287316
[`C` representation]: ../type-layout.md#the-c-representation
317+
[Field-less enums]: #field-less-enum

0 commit comments

Comments
 (0)