non_exhaustive

The tracking issue for this feature is: #44109


The non_exhaustive gate allows you to use the #[non_exhaustive] attribute on structs and enums. 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. Structs marked as non_exhaustive will not be able to be created normally outside of the defining crate. This is demonstrated below:

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", } } }
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 => ..., _ => ..., }
#[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() { // ... }
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;