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:
David Wood 2019-09-20 21:09:39 +01:00
parent dd2df8f97d
commit e0590ea76f
No known key found for this signature in database
GPG Key ID: 2592E76C87381FD9
36 changed files with 30 additions and 155 deletions

View File

@ -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;
```

View File

@ -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)]

View File

@ -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)]

View File

@ -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 { }
```

View File

@ -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)]

View File

@ -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)]

View File

@ -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

View File

@ -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),

View File

@ -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!(

View File

@ -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))]

View File

@ -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() { }

View File

@ -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`.

View File

@ -1,5 +1,4 @@
#![crate_type = "rlib"]
#![feature(non_exhaustive)]
#[non_exhaustive]
pub enum NonExhaustiveEnum {

View File

@ -1,5 +1,3 @@
#![feature(non_exhaustive)]
#[non_exhaustive]
pub struct NormalStruct {
pub first_field: u16,

View File

@ -1,5 +1,4 @@
#![crate_type = "rlib"]
#![feature(non_exhaustive)]
pub enum NonExhaustiveVariants {
#[non_exhaustive] Unit,

View File

@ -1,7 +1,5 @@
// run-pass
#![feature(non_exhaustive)]
#[non_exhaustive]
pub enum NonExhaustiveEnum {
Unit,

View File

@ -1,5 +1,3 @@
#![feature(non_exhaustive)]
#[non_exhaustive]
#[repr(C)]
pub enum NonExhaustiveEnum {

View File

@ -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

View File

@ -1,5 +1,3 @@
#![feature(non_exhaustive)]
#[non_exhaustive(anything)]
//~^ ERROR malformed `non_exhaustive` attribute
struct Foo;

View File

@ -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]
| ^^^^^^^^^^^^^^^^^

View File

@ -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

View File

@ -1,7 +1,6 @@
// run-pass
#![allow(unused_variables)]
#![feature(non_exhaustive)]
#[non_exhaustive]
pub struct NormalStruct {

View File

@ -1,6 +1,5 @@
#![crate_type = "rlib"]
#![feature(never_type)]
#![feature(non_exhaustive)]
#[non_exhaustive]
pub enum UninhabitedEnum {

View File

@ -1,5 +1,4 @@
#![feature(never_type)]
#![feature(non_exhaustive)]
#[non_exhaustive]
pub enum UninhabitedEnum {

View File

@ -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

View File

@ -1,5 +1,4 @@
#![feature(never_type)]
#![feature(non_exhaustive)]
#[non_exhaustive]
pub enum UninhabitedEnum {

View File

@ -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);
| ------------------------------------------------------------

View File

@ -3,7 +3,6 @@
#![deny(unreachable_patterns)]
#![feature(exhaustive_patterns)]
#![feature(never_type)]
#![feature(non_exhaustive)]
#[non_exhaustive]
pub enum UninhabitedEnum {

View File

@ -1,7 +1,6 @@
// aux-build:uninhabited.rs
#![deny(unreachable_patterns)]
#![feature(never_type)]
#![feature(non_exhaustive)]
extern crate uninhabited;

View File

@ -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 { .. } => {},
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1,5 +1,4 @@
#![feature(never_type)]
#![feature(non_exhaustive)]
#[non_exhaustive]
pub enum UninhabitedEnum {

View File

@ -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(!),

View File

@ -3,7 +3,6 @@
#![deny(unreachable_patterns)]
#![feature(exhaustive_patterns)]
#![feature(never_type)]
#![feature(non_exhaustive)]
#[non_exhaustive]
pub enum UninhabitedEnum {

View File

@ -1,7 +1,6 @@
#![deny(unreachable_patterns)]
#![feature(exhaustive_patterns)]
#![feature(never_type)]
#![feature(non_exhaustive)]
#[non_exhaustive]
pub enum UninhabitedEnum {

View File

@ -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() {
| ^^^^^^^^

View File

@ -1,7 +1,5 @@
// run-pass
#![feature(non_exhaustive)]
pub enum NonExhaustiveVariants {
#[non_exhaustive] Unit,
#[non_exhaustive] Tuple(u32),