Skip to content
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

Updated extensibility to discuss non_exhaustive #135

Merged
merged 26 commits into from
Sep 1, 2021
Merged
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Apply suggestions from code review
Co-authored-by: Marco Ieni <11428655+MarcoIeni@users.noreply.github.com>
  • Loading branch information
simonsan and MarcoIeni committed Sep 1, 2021
commit 657e55c6176a41b3444899c19581a64b637c5613
15 changes: 8 additions & 7 deletions idioms/priv-extend.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
# `#[non_exhaustive]` & private fields for extensibility
# `#[non_exhaustive]` and private fields for extensibility

## Description

A small set of scenarios exist where a library author may want to add public
fields to a public struct or new variants to an enum without breaking backwards
compatibility. Rust offers two solutions:
compatibility.
Rust offers two solutions to this problem:

- Use `#[non_exhaustive]` on `struct`s, `enum`s, and `enum` variants.
For extensive documentation on all the places `#[non_exhaustive]` can be used,
see [the docs](https://doc.rust-lang.org/reference/attributes/type_system.html#the-non_exhaustive-attribute).
For extensive documentation on all the places where `#[non_exhaustive]` can be used,
see [the docs](https://doc.rust-lang.org/reference/attributes/type_system.html#the-non_exhaustive-attribute).

- You may add a private field to a struct to prevent it from being directly
instantiated or matched against
simonsan marked this conversation as resolved.
Show resolved Hide resolved

## Warning

Use this deliberately and with caution: Incrementing the major version when adding
Use this deliberately and with caution: incrementing the major version when adding
fields or variants is often a better option. `#[non_exhaustive]` may be appropriate
in scenarios where you're modeling an external resource that may change out-of-sync
with your library, but is not a general purpose tool.

`#[non_exhaustive]` forces clients to handle the "Something else" case; there is
In fact, `#[non_exhaustive]` forces clients to handle the "Something else" case; there is
rarely a sensible action to take in this scenario. This leads to awkward code and
code paths that are only executed in extremely rare circumstances.

Expand Down Expand Up @@ -91,7 +92,7 @@ pub struct S {

## Discussion

On `struct`s `#[non_exhaustive]` allows adding additional fields in a backwards
On `struct`s, `#[non_exhaustive]` allows adding additional fields in a backwards
compatible way. It will also prevent clients from using the struct constructor,
even if all the fields are public. This may be helpful, but it's worth considering
if you _want_ an additional field to be found by clients as a compiler error rather
Expand Down