-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Future-proofing enums/structs with #[non_exhaustive] attribute #2008
Changes from 1 commit
ac2b8be
25d8980
aae8a31
c9c82cf
c358154
61a4b14
3d56889
aa2502f
d7c62c4
09eeb1c
60cf588
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -278,8 +278,8 @@ as well. | |
# Detailed design | ||
|
||
An attribute `#[non_exhaustive]` is added to the language, which will (for now) | ||
fail to compile if it's used on anything other than an enum, struct definition, | ||
or enum variant. | ||
fail to compile if it's used on anything other than an enum or struct | ||
definition, or enum variant. | ||
|
||
## Enums | ||
|
||
|
@@ -417,6 +417,10 @@ Then we the only valid way of matching will be: | |
let Config { 0: width, 1: height, .. } = config; | ||
``` | ||
|
||
We can think of this as lowering the visibility of the constructor to | ||
`pub(crate)` if it is marked as `pub`, then applying the standard structure | ||
rules. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs to apply to unit structs as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do; one sec. |
||
|
||
## Unit structs | ||
|
||
Unit structs will work very similarly to tuple structs. Consider this struct: | ||
|
@@ -433,6 +437,41 @@ match it like: | |
let Unit { .. } = unit; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as previously, the constructor's visibility need to be adjusted |
||
``` | ||
|
||
To users of this crate, this will act exactly as if the struct were defined as: | ||
|
||
``` | ||
#[non_exhaustive] | ||
pub struct Unit {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, this seems to be equivalent to 3d56889#r135395315, but I'd still prefer to use the same wording for tuple and unit structs. |
||
``` | ||
|
||
## Functional record updates | ||
|
||
Functional record updates will operate exactly the same regardless of whether | ||
structs are marked as non-exhaustive or not. For example, given this struct: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, the decision was the opposite - FRU is not permitted with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought that FRU still worked when structs have private fields? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No :( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unless I'm misunderstanding, I tried this out on the playground and it seems to work: https://play.rust-lang.org/?gist=eabe36303f9da0ced44c237ca3b29d45&version=stable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. …right, I'll update the RFC. |
||
|
||
``` | ||
#[derive(Debug)] | ||
#[non_exhaustive] | ||
pub struct Config { | ||
pub width: u16, | ||
pub height: u16, | ||
pub fullscreen: bool, | ||
} | ||
impl Default for Config { | ||
fn default() -> Config { | ||
Config { width: 640, height: 480, fullscreen: false } | ||
} | ||
} | ||
``` | ||
|
||
The below code will print `Config { width: 1920, height: 1080, fullscreen: | ||
false }` regardless of which crate is calling it: | ||
|
||
``` | ||
let c = Config { width: 1920, height: 1080, ..Config::default() }; | ||
println!("{:?}", c); | ||
``` | ||
|
||
## Changes to rustdoc | ||
|
||
Right now, the only indicator that rustdoc gives for non-exhaustive enums and | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, FRU expressions should be legal here as well.