Skip to content

Commit 61cd0a8

Browse files
obi1kenobiehuss
authored andcommitted
Document that adding #[non_exhaustive] is a major breaking change.
1 parent ee7f4c3 commit 61cd0a8

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

src/doc/src/reference/semver.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ considered incompatible.
9090
* [Major: generalizing a function to use generics with type mismatch](#fn-generalize-mismatch)
9191
* Attributes
9292
* [Major: switching from `no_std` support to requiring `std`](#attr-no-std-to-std)
93+
* [Major: adding `non_exhaustive` to an existing enum, variant, or struct with no private fields](#attr-adding-non-exhaustive)
9394
* Tooling and environment compatibility
9495
* [Possibly-breaking: changing the minimum version of Rust required](#env-new-rust)
9596
* [Possibly-breaking: changing the platform and environment requirements](#env-change-requirements)
@@ -1115,6 +1116,81 @@ Mitigation strategies:
11151116
optionally enables `std` support, and when the feature is off, the library
11161117
can be used in a `no_std` environment.
11171118

1119+
<a id="attr-adding-non-exhaustive"></a>
1120+
### Major: adding `non_exhaustive` to an existing enum, variant, or struct with no private fields
1121+
1122+
Making items [`#[non_exhaustive]`][non_exhaustive] changes how they may
1123+
be used outside the crate where they are defined:
1124+
- Non-exhaustive structs and enum variants cannot be constructed
1125+
using [struct literal] syntax, including [functional update syntax].
1126+
- Pattern matching on non-exhaustive enums always requires
1127+
a wildcard (`_`) arm.
1128+
1129+
Structs with private fields cannot be constructed using [struct literal] syntax
1130+
regardless of whether [`#[non_exhaustive]`][non_exhaustive] is used.
1131+
Adding [`#[non_exhaustive]`][non_exhaustive] to such a struct is not
1132+
a breaking change.
1133+
1134+
```rust,ignore
1135+
// MAJOR CHANGE
1136+
1137+
///////////////////////////////////////////////////////////
1138+
// Before
1139+
pub struct Foo {
1140+
pub bar: usize,
1141+
}
1142+
1143+
pub enum Bar {
1144+
Baz,
1145+
}
1146+
1147+
pub enum Quux {
1148+
X,
1149+
Y(a: usize),
1150+
Z { b: usize },
1151+
}
1152+
1153+
///////////////////////////////////////////////////////////
1154+
// After
1155+
#[non_exhaustive]
1156+
pub struct Foo {
1157+
pub bar: usize,
1158+
}
1159+
1160+
pub enum Bar {
1161+
#[non_exhaustive] X,
1162+
#[non_exhaustive] Y(usize),
1163+
#[non_exhaustive] Z { a: usize },
1164+
}
1165+
1166+
#[non_exhaustive]
1167+
pub enum Quux {
1168+
Var,
1169+
}
1170+
1171+
///////////////////////////////////////////////////////////
1172+
// Example usage that will break.
1173+
use updated_crate::{Foo, Bar, Quux};
1174+
1175+
fn main() {
1176+
let foo = Foo { bar: 0 }; // Error: cannot create non-exhaustive struct using struct expression
1177+
1178+
let bar_x = Bar::X; // Error: unit variant `X` is private
1179+
let bar_y = Bar::Y(0); // Error: tuple variant `Y` is private
1180+
let bar_z = Bar::Z { a: 0 }; // Error: cannot create non-exhaustive variant using struct expression
1181+
1182+
let q = Quux::Var;
1183+
match q { // Error: non-exhaustive patterns: `_` not covered
1184+
Quux::Var => 0,
1185+
}
1186+
}
1187+
```
1188+
1189+
Mitigation strategies:
1190+
* Mark structs, enums, and enum variants as
1191+
[`#[non_exhaustive]`][non_exhaustive] when first introducing them,
1192+
rather than adding [`#[non_exhaustive]`][non_exhaustive] later on.
1193+
11181194
## Tooling and environment compatibility
11191195

11201196
<a id="env-new-rust"></a>
@@ -1393,6 +1469,7 @@ document what your commitments are.
13931469
[Default]: ../../std/default/trait.Default.html
13941470
[deprecated]: ../../reference/attributes/diagnostics.html#the-deprecated-attribute
13951471
[disambiguation syntax]: ../../reference/expressions/call-expr.html#disambiguating-function-calls
1472+
[functional update syntax]: ../../reference/expressions/struct-expr.html#functional-update-syntax
13961473
[inherent implementations]: ../../reference/items/implementations.html#inherent-implementations
13971474
[items]: ../../reference/items.html
13981475
[non_exhaustive]: ../../reference/attributes/type_system.html#the-non_exhaustive-attribute

0 commit comments

Comments
 (0)