RFC 2008: Stabilization
This commit stabilizes RFC 2008 (#44109) by removing the feature gate. Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
parent
dd2df8f97d
commit
e0590ea76f
|
@ -1,76 +0,0 @@
|
|||
# `non_exhaustive`
|
||||
|
||||
The tracking issue for this feature is: [#44109]
|
||||
|
||||
[#44109]: https://github.com/rust-lang/rust/issues/44109
|
||||
|
||||
------------------------
|
||||
|
||||
The `non_exhaustive` gate allows you to use the `#[non_exhaustive]` attribute
|
||||
on structs, enums and enum variants. When applied within a crate, users of the
|
||||
crate will need to use the `_` pattern when matching enums and use the `..`
|
||||
pattern when matching structs. Enum variants cannot be matched against.
|
||||
Structs and enum variants marked as `non_exhaustive` will not be able to
|
||||
be created normally outside of the defining crate. This is demonstrated
|
||||
below:
|
||||
|
||||
```rust,ignore (pseudo-Rust)
|
||||
use std::error::Error as StdError;
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum Error {
|
||||
Message(String),
|
||||
Other,
|
||||
}
|
||||
impl StdError for Error {
|
||||
fn description(&self) -> &str {
|
||||
// This will not error, despite being marked as non_exhaustive, as this
|
||||
// enum is defined within the current crate, it can be matched
|
||||
// exhaustively.
|
||||
match *self {
|
||||
Message(ref s) => s,
|
||||
Other => "other or unknown error",
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```rust,ignore (pseudo-Rust)
|
||||
use mycrate::Error;
|
||||
|
||||
// This will not error as the non_exhaustive Error enum has been matched with
|
||||
// a wildcard.
|
||||
match error {
|
||||
Message(ref s) => ...,
|
||||
Other => ...,
|
||||
_ => ...,
|
||||
}
|
||||
```
|
||||
|
||||
```rust,ignore (pseudo-Rust)
|
||||
#[non_exhaustive]
|
||||
pub struct Config {
|
||||
pub window_width: u16,
|
||||
pub window_height: u16,
|
||||
}
|
||||
|
||||
// We can create structs as normal within the defining crate when marked as
|
||||
// non_exhaustive.
|
||||
let config = Config { window_width: 640, window_height: 480 };
|
||||
|
||||
// We can match structs exhaustively when within the defining crate.
|
||||
if let Ok(Config { window_width, window_height }) = load_config() {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
```rust,ignore (pseudo-Rust)
|
||||
use mycrate::Config;
|
||||
|
||||
// We cannot create a struct like normal if it has been marked as
|
||||
// non_exhaustive.
|
||||
let config = Config { window_width: 640, window_height: 480 };
|
||||
// By adding the `..` we can match the config as below outside of the crate
|
||||
// when marked non_exhaustive.
|
||||
let &Config { window_width, window_height, .. } = config;
|
||||
```
|
|
@ -121,7 +121,7 @@
|
|||
#![feature(hexagon_target_feature)]
|
||||
#![feature(const_int_conversion)]
|
||||
#![feature(const_transmute)]
|
||||
#![feature(non_exhaustive)]
|
||||
#![cfg_attr(bootstrap, feature(non_exhaustive))]
|
||||
#![feature(structural_match)]
|
||||
#![feature(abi_unadjusted)]
|
||||
#![feature(adx_target_feature)]
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#![feature(extern_types)]
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(non_exhaustive)]
|
||||
#![cfg_attr(bootstrap, feature(non_exhaustive))]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(specialization)]
|
||||
|
||||
|
|
|
@ -2105,8 +2105,6 @@ on something other than a struct or enum.
|
|||
Examples of erroneous code:
|
||||
|
||||
```compile_fail,E0701
|
||||
# #![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
trait Foo { }
|
||||
```
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#![feature(overlapping_marker_traits)]
|
||||
#![feature(extern_types)]
|
||||
#![feature(nll)]
|
||||
#![feature(non_exhaustive)]
|
||||
#![cfg_attr(bootstrap, feature(non_exhaustive))]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(option_expect_none)]
|
||||
#![feature(range_is_empty)]
|
||||
|
|
|
@ -283,7 +283,7 @@
|
|||
#![feature(needs_panic_runtime)]
|
||||
#![feature(never_type)]
|
||||
#![feature(nll)]
|
||||
#![feature(non_exhaustive)]
|
||||
#![cfg_attr(bootstrap, feature(non_exhaustive))]
|
||||
#![feature(on_unimplemented)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(panic_info_message)]
|
||||
|
|
|
@ -245,8 +245,10 @@ declare_features! (
|
|||
(accepted, bind_by_move_pattern_guards, "1.39.0", Some(15287), None),
|
||||
/// Allows attributes in formal function parameters.
|
||||
(accepted, param_attrs, "1.39.0", Some(60406), None),
|
||||
// Allows macro invocations in `extern {}` blocks.
|
||||
/// Allows macro invocations in `extern {}` blocks.
|
||||
(accepted, macros_in_extern, "1.40.0", Some(49476), None),
|
||||
/// Allows future-proofing enums/structs with the `#[non_exhaustive]` attribute (RFC 2008).
|
||||
(accepted, non_exhaustive, "1.40.0", Some(44109), None),
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// feature-group-end: accepted features
|
||||
|
|
|
@ -383,9 +383,6 @@ declare_features! (
|
|||
/// Allows `#[doc(include = "some-file")]`.
|
||||
(active, external_doc, "1.22.0", Some(44732), None),
|
||||
|
||||
/// Allows future-proofing enums/structs with the `#[non_exhaustive]` attribute (RFC 2008).
|
||||
(active, non_exhaustive, "1.22.0", Some(44109), None),
|
||||
|
||||
/// Allows using `crate` as visibility modifier, synonymous with `pub(crate)`.
|
||||
(active, crate_visibility_modifier, "1.23.0", Some(53120), None),
|
||||
|
||||
|
|
|
@ -252,6 +252,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
ungated!(path, Normal, template!(NameValueStr: "file")),
|
||||
ungated!(no_std, CrateLevel, template!(Word)),
|
||||
ungated!(no_implicit_prelude, Normal, template!(Word)),
|
||||
ungated!(non_exhaustive, Whitelisted, template!(Word)),
|
||||
|
||||
// Runtime
|
||||
ungated!(windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console")),
|
||||
|
@ -314,9 +315,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
test_runner, CrateLevel, template!(List: "path"), custom_test_frameworks,
|
||||
"custom test frameworks are an unstable feature",
|
||||
),
|
||||
|
||||
// RFC #2008
|
||||
gated!(non_exhaustive, Whitelisted, template!(Word), experimental!(non_exhaustive)),
|
||||
// RFC #1268
|
||||
gated!(marker, Normal, template!(Word), marker_trait_attr, experimental!(marker)),
|
||||
gated!(
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#![feature(const_fn)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(nll)]
|
||||
#![feature(non_exhaustive)]
|
||||
#![cfg_attr(bootstrap, feature(non_exhaustive))]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![cfg_attr(bootstrap, feature(proc_macro_hygiene))]
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
//#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive] //~ERROR the `#[non_exhaustive]` attribute is an experimental feature
|
||||
pub enum NonExhaustiveEnum {
|
||||
Unit,
|
||||
Tuple(u32),
|
||||
Struct { field: u32 }
|
||||
}
|
||||
|
||||
fn main() { }
|
|
@ -1,12 +0,0 @@
|
|||
error[E0658]: the `#[non_exhaustive]` attribute is an experimental feature
|
||||
--> $DIR/feature-gate-non_exhaustive.rs:3:1
|
||||
|
|
||||
LL | #[non_exhaustive]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/44109
|
||||
= help: add `#![feature(non_exhaustive)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -1,5 +1,4 @@
|
|||
#![crate_type = "rlib"]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum NonExhaustiveEnum {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct NormalStruct {
|
||||
pub first_field: u16,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#![crate_type = "rlib"]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
pub enum NonExhaustiveVariants {
|
||||
#[non_exhaustive] Unit,
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// run-pass
|
||||
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum NonExhaustiveEnum {
|
||||
Unit,
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
#[repr(C)]
|
||||
pub enum NonExhaustiveEnum {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// check-pass
|
||||
#![feature(non_exhaustive)]
|
||||
#![deny(improper_ctypes)]
|
||||
|
||||
// This test checks that non-exhaustive types with `#[repr(C)]` are considered proper within
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive(anything)]
|
||||
//~^ ERROR malformed `non_exhaustive` attribute
|
||||
struct Foo;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error: malformed `non_exhaustive` attribute input
|
||||
--> $DIR/invalid-attribute.rs:3:1
|
||||
--> $DIR/invalid-attribute.rs:1:1
|
||||
|
|
||||
LL | #[non_exhaustive(anything)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[non_exhaustive]`
|
||||
|
||||
error[E0701]: attribute can only be applied to a struct or enum
|
||||
--> $DIR/invalid-attribute.rs:7:1
|
||||
--> $DIR/invalid-attribute.rs:5:1
|
||||
|
|
||||
LL | #[non_exhaustive]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
@ -14,7 +14,7 @@ LL | trait Bar { }
|
|||
| ------------- not a struct or enum
|
||||
|
||||
error[E0701]: attribute can only be applied to a struct or enum
|
||||
--> $DIR/invalid-attribute.rs:11:1
|
||||
--> $DIR/invalid-attribute.rs:9:1
|
||||
|
|
||||
LL | #[non_exhaustive]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -16,7 +16,7 @@ error[E0603]: tuple struct constructor `TupleStruct` is private
|
|||
LL | let ts_explicit = structs::TupleStruct(640, 480);
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
::: $DIR/auxiliary/structs.rs:13:24
|
||||
::: $DIR/auxiliary/structs.rs:11:24
|
||||
|
|
||||
LL | pub struct TupleStruct(pub u16, pub u16);
|
||||
| ---------------- a constructor is private if any of the fields is private
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// run-pass
|
||||
|
||||
#![allow(unused_variables)]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct NormalStruct {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#![crate_type = "rlib"]
|
||||
#![feature(never_type)]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum UninhabitedEnum {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#![feature(never_type)]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum UninhabitedEnum {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/coercions_same_crate.rs:31:5
|
||||
--> $DIR/coercions_same_crate.rs:30:5
|
||||
|
|
||||
LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A {
|
||||
| - expected `A` because of return type
|
||||
|
@ -10,7 +10,7 @@ LL | x
|
|||
found type `UninhabitedEnum`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/coercions_same_crate.rs:35:5
|
||||
--> $DIR/coercions_same_crate.rs:34:5
|
||||
|
|
||||
LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
|
||||
| - expected `A` because of return type
|
||||
|
@ -21,7 +21,7 @@ LL | x
|
|||
found type `UninhabitedTupleStruct`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/coercions_same_crate.rs:39:5
|
||||
--> $DIR/coercions_same_crate.rs:38:5
|
||||
|
|
||||
LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A {
|
||||
| - expected `A` because of return type
|
||||
|
@ -32,7 +32,7 @@ LL | x
|
|||
found type `UninhabitedStruct`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/coercions_same_crate.rs:43:5
|
||||
--> $DIR/coercions_same_crate.rs:42:5
|
||||
|
|
||||
LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A {
|
||||
| - expected `A` because of return type
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#![feature(never_type)]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum UninhabitedEnum {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedEnum` of type `IndirectUninhabitedEnum` is not handled
|
||||
--> $DIR/indirect_match_same_crate.rs:35:11
|
||||
--> $DIR/indirect_match_same_crate.rs:34:11
|
||||
|
|
||||
LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum);
|
||||
| ----------------------------------------------------
|
||||
|
@ -13,7 +13,7 @@ LL | match x {}
|
|||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedStruct` of type `IndirectUninhabitedStruct` is not handled
|
||||
--> $DIR/indirect_match_same_crate.rs:39:11
|
||||
--> $DIR/indirect_match_same_crate.rs:38:11
|
||||
|
|
||||
LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct);
|
||||
| --------------------------------------------------------
|
||||
|
@ -27,7 +27,7 @@ LL | match x {}
|
|||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedTupleStruct` of type `IndirectUninhabitedTupleStruct` is not handled
|
||||
--> $DIR/indirect_match_same_crate.rs:43:11
|
||||
--> $DIR/indirect_match_same_crate.rs:42:11
|
||||
|
|
||||
LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
|
||||
| ------------------------------------------------------------------
|
||||
|
@ -41,7 +41,7 @@ LL | match x {}
|
|||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedVariants` of type `IndirectUninhabitedVariants` is not handled
|
||||
--> $DIR/indirect_match_same_crate.rs:49:11
|
||||
--> $DIR/indirect_match_same_crate.rs:48:11
|
||||
|
|
||||
LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants);
|
||||
| ------------------------------------------------------------
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#![deny(unreachable_patterns)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(never_type)]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum UninhabitedEnum {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// aux-build:uninhabited.rs
|
||||
#![deny(unreachable_patterns)]
|
||||
#![feature(never_type)]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
extern crate uninhabited;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: unreachable pattern
|
||||
--> $DIR/issue-65157-repeated-match-arm.rs:16:9
|
||||
--> $DIR/issue-65157-repeated-match-arm.rs:15:9
|
||||
|
|
||||
LL | PartiallyInhabitedVariants::Struct { .. } => {},
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#![feature(never_type)]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum UninhabitedEnum {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0004]: non-exhaustive patterns: pattern `UninhabitedStruct` of type `UninhabitedStruct` is not handled
|
||||
--> $DIR/match_same_crate.rs:31:11
|
||||
--> $DIR/match_same_crate.rs:30:11
|
||||
|
|
||||
LL | pub struct UninhabitedStruct {
|
||||
| - ----------------- variant not covered
|
||||
|
@ -15,7 +15,7 @@ LL | match x {}
|
|||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: pattern `UninhabitedTupleStruct` of type `UninhabitedTupleStruct` is not handled
|
||||
--> $DIR/match_same_crate.rs:35:11
|
||||
--> $DIR/match_same_crate.rs:34:11
|
||||
|
|
||||
LL | pub struct UninhabitedTupleStruct(!);
|
||||
| -------------------------------------
|
||||
|
@ -29,7 +29,7 @@ LL | match x {}
|
|||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: multiple patterns of type `UninhabitedVariants` are not handled
|
||||
--> $DIR/match_same_crate.rs:39:11
|
||||
--> $DIR/match_same_crate.rs:38:11
|
||||
|
|
||||
LL | / pub enum UninhabitedVariants {
|
||||
LL | | #[non_exhaustive] Tuple(!),
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#![deny(unreachable_patterns)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(never_type)]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum UninhabitedEnum {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#![deny(unreachable_patterns)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(never_type)]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum UninhabitedEnum {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: unreachable pattern
|
||||
--> $DIR/patterns_same_crate.rs:53:9
|
||||
--> $DIR/patterns_same_crate.rs:52:9
|
||||
|
|
||||
LL | Some(_x) => (),
|
||||
| ^^^^^^^^
|
||||
|
@ -11,25 +11,25 @@ LL | #![deny(unreachable_patterns)]
|
|||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/patterns_same_crate.rs:58:9
|
||||
--> $DIR/patterns_same_crate.rs:57:9
|
||||
|
|
||||
LL | Some(_x) => (),
|
||||
| ^^^^^^^^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/patterns_same_crate.rs:62:15
|
||||
--> $DIR/patterns_same_crate.rs:61:15
|
||||
|
|
||||
LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/patterns_same_crate.rs:66:15
|
||||
--> $DIR/patterns_same_crate.rs:65:15
|
||||
|
|
||||
LL | while let Some(_x) = uninhabited_struct() {
|
||||
| ^^^^^^^^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/patterns_same_crate.rs:69:15
|
||||
--> $DIR/patterns_same_crate.rs:68:15
|
||||
|
|
||||
LL | while let Some(_x) = uninhabited_tuple_struct() {
|
||||
| ^^^^^^^^
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// run-pass
|
||||
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
pub enum NonExhaustiveVariants {
|
||||
#[non_exhaustive] Unit,
|
||||
#[non_exhaustive] Tuple(u32),
|
||||
|
|
Loading…
Reference in New Issue