Skip to content

Commit 02b27f1

Browse files
committed
Auto merge of rust-lang#86860 - fee1-dead:stabilize, r=LeSeulArtichaut
Stabilize `arbitrary_enum_discriminant` Closes rust-lang#60553. ---- ## Stabilization Report _copied from rust-lang#60553 (comment) ### Summary Enables a user to specify *explicit* discriminants on arbitrary enums. Previously, this was hard to achieve: ```rust #[repr(u8)] enum Foo { A(u8) = 0, B(i8) = 1, C(bool) = 42, } ``` Someone would need to add 41 hidden variants in between as a workaround with implicit discriminants. In conjunction with [RFC 2195](https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md), this feature would provide more flexibility for FFI and unsafe code involving enums. ### Test cases Most tests are in [`src/test/ui/enum-discriminant`](https://github.com/rust-lang/rust/tree/master/src/test/ui/enum-discriminant), there are two [historical](https://github.com/rust-lang/rust/blob/master/src/test/ui/parser/tag-variant-disr-non-nullary.rs) [tests](https://github.com/rust-lang/rust/blob/master/src/test/ui/parser/issue-17383.rs) that are now covered by the feature (removed by this pr due to them being obsolete). ### Edge cases The feature is well defined and does not have many edge cases. One [edge case](rust-lang#70509) was related to another unstable feature named `repr128` and is resolved. ### Previous PRs The [implementation PR](rust-lang#60732) added documentation to the Unstable Book, rust-lang/reference#1055 was opened as a continuation of rust-lang/reference#639. ### Resolution of unresolved questions The questions are resolved in rust-lang#60553 (comment). ---- (someone please add `needs-fcp`)
2 parents adf1688 + 7a62f29 commit 02b27f1

21 files changed

+13
-221
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

+2-62
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use rustc_ast as ast;
22
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
33
use rustc_ast::{AssocTyConstraint, AssocTyConstraintKind, NodeId};
4-
use rustc_ast::{PatKind, RangeEnd, VariantData};
4+
use rustc_ast::{PatKind, RangeEnd};
55
use rustc_errors::struct_span_err;
66
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
77
use rustc_feature::{Features, GateIssue};
8-
use rustc_session::parse::{feature_err, feature_err_issue};
8+
use rustc_session::parse::feature_err_issue;
99
use rustc_session::Session;
1010
use rustc_span::source_map::Spanned;
1111
use rustc_span::symbol::sym;
@@ -218,46 +218,6 @@ impl<'a> PostExpansionVisitor<'a> {
218218
}
219219
}
220220

221-
fn maybe_report_invalid_custom_discriminants(&self, variants: &[ast::Variant]) {
222-
let has_fields = variants.iter().any(|variant| match variant.data {
223-
VariantData::Tuple(..) | VariantData::Struct(..) => true,
224-
VariantData::Unit(..) => false,
225-
});
226-
227-
let discriminant_spans = variants
228-
.iter()
229-
.filter(|variant| match variant.data {
230-
VariantData::Tuple(..) | VariantData::Struct(..) => false,
231-
VariantData::Unit(..) => true,
232-
})
233-
.filter_map(|variant| variant.disr_expr.as_ref().map(|c| c.value.span))
234-
.collect::<Vec<_>>();
235-
236-
if !discriminant_spans.is_empty() && has_fields {
237-
let mut err = feature_err(
238-
&self.sess.parse_sess,
239-
sym::arbitrary_enum_discriminant,
240-
discriminant_spans.clone(),
241-
"custom discriminant values are not allowed in enums with tuple or struct variants",
242-
);
243-
for sp in discriminant_spans {
244-
err.span_label(sp, "disallowed custom discriminant");
245-
}
246-
for variant in variants.iter() {
247-
match &variant.data {
248-
VariantData::Struct(..) => {
249-
err.span_label(variant.span, "struct variant defined here");
250-
}
251-
VariantData::Tuple(..) => {
252-
err.span_label(variant.span, "tuple variant defined here");
253-
}
254-
VariantData::Unit(..) => {}
255-
}
256-
}
257-
err.emit();
258-
}
259-
}
260-
261221
fn check_gat(&self, generics: &ast::Generics, span: Span) {
262222
if !generics.params.is_empty() {
263223
gate_feature_post!(
@@ -402,26 +362,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
402362
}
403363
}
404364

405-
ast::ItemKind::Enum(ast::EnumDef { ref variants, .. }, ..) => {
406-
for variant in variants {
407-
match (&variant.data, &variant.disr_expr) {
408-
(ast::VariantData::Unit(..), _) => {}
409-
(_, Some(disr_expr)) => gate_feature_post!(
410-
&self,
411-
arbitrary_enum_discriminant,
412-
disr_expr.value.span,
413-
"discriminants on non-unit variants are experimental"
414-
),
415-
_ => {}
416-
}
417-
}
418-
419-
let has_feature = self.features.arbitrary_enum_discriminant;
420-
if !has_feature && !i.span.allows_unstable(sym::arbitrary_enum_discriminant) {
421-
self.maybe_report_invalid_custom_discriminants(&variants);
422-
}
423-
}
424-
425365
ast::ItemKind::Impl(box ast::ImplKind {
426366
polarity, defaultness, ref of_trait, ..
427367
}) => {

compiler/rustc_error_codes/src/error_codes/E0732.md

-4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ An `enum` with a discriminant must specify a `#[repr(inttype)]`.
33
Erroneous code example:
44

55
```compile_fail,E0732
6-
#![feature(arbitrary_enum_discriminant)]
7-
86
enum Enum { // error!
97
Unit = 1,
108
Tuple() = 2,
@@ -20,8 +18,6 @@ is a well-defined way to extract a variant's discriminant from a value;
2018
for instance:
2119

2220
```
23-
#![feature(arbitrary_enum_discriminant)]
24-
2521
#[repr(u8)]
2622
enum Enum {
2723
Unit = 3,

compiler/rustc_feature/src/accepted.rs

+2
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,8 @@ declare_features! (
294294
(accepted, const_fn_transmute, "1.56.0", Some(53605), None),
295295
/// Allows accessing fields of unions inside `const` functions.
296296
(accepted, const_fn_union, "1.56.0", Some(51909), None),
297+
/// Allows explicit discriminants on non-unit enum variants.
298+
(accepted, arbitrary_enum_discriminant, "1.56.0", Some(60553), None),
297299

298300
// -------------------------------------------------------------------------
299301
// feature-group-end: accepted features

compiler/rustc_feature/src/active.rs

-3
Original file line numberDiff line numberDiff line change
@@ -471,9 +471,6 @@ declare_features! (
471471
/// Allows #[repr(transparent)] on unions (RFC 2645).
472472
(active, transparent_unions, "1.37.0", Some(60405), None),
473473

474-
/// Allows explicit discriminants on non-unit enum variants.
475-
(active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None),
476-
477474
/// Allows `async || body` closures.
478475
(active, async_closure, "1.37.0", Some(62290), None),
479476

compiler/rustc_typeck/src/check/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1383,7 +1383,7 @@ fn check_enum<'tcx>(
13831383
}
13841384
}
13851385

1386-
if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
1386+
if tcx.adt_def(def_id).repr.int.is_none() {
13871387
let is_unit = |var: &hir::Variant<'_>| matches!(var.data, hir::VariantData::Unit(..));
13881388

13891389
let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();

src/doc/unstable-book/src/language-features/arbitrary-enum-discriminant.md

-37
This file was deleted.

src/test/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#![crate_type="lib"]
2-
#![feature(arbitrary_enum_discriminant)]
32

43
enum Enum {
54
//~^ ERROR `#[repr(inttype)]` must be specified

src/test/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0732]: `#[repr(inttype)]` must be specified
2-
--> $DIR/arbitrary_enum_discriminant-no-repr.rs:4:1
2+
--> $DIR/arbitrary_enum_discriminant-no-repr.rs:3:1
33
|
44
LL | / enum Enum {
55
LL | |

src/test/ui/enum-discriminant/arbitrary_enum_discriminant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// run-pass
2-
#![feature(arbitrary_enum_discriminant, const_raw_ptr_deref, test)]
2+
#![feature(const_raw_ptr_deref, test)]
33

44
extern crate test;
55

src/test/ui/enum-discriminant/discriminant_value.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// run-pass
22
#![allow(stable_features)]
3-
#![feature(arbitrary_enum_discriminant, core, core_intrinsics)]
3+
#![feature(core, core_intrinsics)]
44

55
extern crate core;
66
use core::intrinsics::discriminant_value;

src/test/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.rs

-10
This file was deleted.

src/test/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.stderr

-36
This file was deleted.

src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(arbitrary_enum_discriminant, core_intrinsics)]
1+
#![feature(core_intrinsics)]
22

33
extern crate core;
44
use core::intrinsics::discriminant_value;

src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(arbitrary_enum_discriminant, core_intrinsics)]
1+
#![feature(core_intrinsics)]
22

33
extern crate core;
44
use core::intrinsics::discriminant_value;

src/test/ui/enum-discriminant/issue-70509-partial_eq.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// run-pass
2-
#![feature(repr128, arbitrary_enum_discriminant)]
2+
#![feature(repr128)]
33
//~^ WARN the feature `repr128` is incomplete
44

55
#[derive(PartialEq, Debug)]

src/test/ui/enum-discriminant/issue-70509-partial_eq.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
warning: the feature `repr128` is incomplete and may not be safe to use and/or cause compiler crashes
22
--> $DIR/issue-70509-partial_eq.rs:2:12
33
|
4-
LL | #![feature(repr128, arbitrary_enum_discriminant)]
4+
LL | #![feature(repr128)]
55
| ^^^^^^^
66
|
77
= note: `#[warn(incomplete_features)]` on by default

src/test/ui/intrinsics/panic-uninitialized-zeroed.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
// This test checks panic emitted from `mem::{uninitialized,zeroed}`.
77

8-
#![feature(never_type, arbitrary_enum_discriminant)]
8+
#![feature(never_type)]
99
#![allow(deprecated, invalid_value)]
1010

1111
use std::{

src/test/ui/parser/issue-17383.rs

-7
This file was deleted.

src/test/ui/parser/issue-17383.stderr

-15
This file was deleted.

src/test/ui/parser/tag-variant-disr-non-nullary.rs

-12
This file was deleted.

src/test/ui/parser/tag-variant-disr-non-nullary.stderr

-25
This file was deleted.

0 commit comments

Comments
 (0)