Repository: rust
Issue: Tracking issue for RFC 3681: Default field values
Labels: T-lang,T-compiler,B-unstable,C-tracking-issue,F-default_field_values

<!--
NOTE: For library features, please use the "Library Tracking Issue" template instead.

Thank you for creating a tracking issue! 📜 Tracking issues are for tracking a
feature from implementation to stabilisation. Make sure to include the relevant
RFC for the feature if it has one. Otherwise provide a short summary of the
feature and link any relevant PRs or issues, and remove any sections that are
not relevant to the feature.

Remember to add team labels to the tracking issue.
For a language team feature, this would e.g., be `T-lang`.
Such a feature should also be labeled with e.g., `F-my_feature`.
This label is used to associate issues (e.g., bugs and design questions) to the feature.
-->

This is a tracking issue for the RFC "3681" (rust-lang/rfcs#3681).
The feature gate for the issue is `#![feature(default_field_values)]`.

Allow `struct` definitions to provide default values for individual fields and
thereby allowing those to be omitted from initializers. When deriving `Default`,
the provided values will then be used. For example:

```rust
#[derive(Default)]
struct Pet {
    name: Option<String>, // impl Default for Pet will use Default::default() for name
    age: i128 = 42, // impl Default for Pet will use the literal 42 for age
}

let valid = Pet { name: None, .. };
assert_eq!(valid.age, 42);
let default = Pet::default();
assert_eq!(default.age, 42);

let invalid = Pet { .. };
```

### About tracking issues

Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however *not* meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
Discussion comments will get marked as off-topic or deleted.
Repeated discussions on the tracking issue may lead to the tracking issue getting locked.

### Steps
<!--
Include each step required to complete the feature. Typically this is a PR
implementing a feature, followed by a PR that stabilises the feature. However
for larger features an implementation could be broken up into multiple PRs.
-->

- [ ] Implement the RFC (cc @rust-lang/compiler)
    - [x] Parse the new syntax
    - [x] Support `#[derive(Default)]` expansion of structs with default field values
    - [x] Support `#[derive(Default)]` expansion of struct variants where every field has a default
    - [x] Restrict `#[non_exhaustive]` on items with default field values
    - [x] Restrict defaults on tuple struct and tuple variants
    - [x] Define visibility of defaulted field values on value construction (`S { .. }` is allowed if `a` in `struct S { a: () }` is not visible?)
    - [x] Restrict `S { .. }` when `S` has no fields with default values
    - [x] Lint against explicit `impl Default` when `#[derive(Default)]` would be ok
      - [ ] Additional lints for iffy cases (maybe belongs in clippy?)
- [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide])
    - [x] Add unstable book entry
    - [ ] Add to the Reference
    - [ ] Mention in The Book
    - [ ] Add example to Rust By Example
- [ ] Formatting for new syntax has been added to the [Style Guide] ([nightly-style-procedure])
- [ ] Stabilization PR ([see instructions on rustc-dev-guide][stabilization-guide])

[stabilization-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#stabilization-pr
[doc-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#documentation-prs
[nightly-style-procedure]: https://github.com/rust-lang/style-team/blob/master/nightly-style-procedure.md 
[Style Guide]: https://github.com/rust-lang/rust/tree/master/src/doc/style-guide

### Unresolved Questions
<!--
Include any open questions that need to be answered before the feature can be
stabilised.
-->
 - ~What is the right interaction wrt. `#[non_exhaustive]`?~ Made mutually exclusive.
 - ~Customization of behavior wrt. visibility rules (allow user to specify that value can be constructed with `..` covering defaulted field that otherwise is not accessible)~ Following RFC: struct can't be constructed with `..` if it covers a private field.
 - ~Allowing `..` on types with no default fields, particularly in unit structs?*~ Disallowed, can be added later if we find a reason to support that.
 - ~Allowing the use of `field_name: _` to specify the use of the default for that specific field?*~ Let's not try that, particularly in the face of `~const Default` allowing for `field_name: Default::default()` and `field_name: default()`
 - ~Tuple structs and tuple variant support*~ Let file a subsequent RFC for this.
 - Integration with (potential, at this time) structural records*
 - Integration with (potential, at this time) literal type inference (`_ { .. }`)*
 - ~Exposing default field values as individual consts in the syntax? (I lean towards "unneeded")~ If an API needs the default to be expressed, it can be an associated `const` and use `field_name: Self::CONST_DEFAULT`, making it accessible
 - Expand support to non-const values? (Personal position is that we shouldn't do that, particularly seeing how powerful const eval is becoming.)

\* *Decision not needed for stabilization of this feature, can be follow up work.*

### Implementation history

<!--
Include a list of all the PRs that were involved in implementing the feature.
-->

- Initial implementation:
https://github.com/rust-lang/rust/pull/129514
- Minor test add:
https://github.com/rust-lang/rust/pull/134136
- Make sure to use normalized ty for unevaluated const in default struct value [ICE fix]:
https://github.com/rust-lang/rust/pull/134314
- Lints for `Default` impls that could diverge against default field values:
https://github.com/rust-lang/rust/pull/134441
  - Only lint for "manual `impl Default` without using `..` for all default fields":
https://github.com/rust-lang/rust/pull/134737
  - 1st Experiment:
https://github.com/rust-lang/rust/pull/134175
  - Reuse logic from #134441 that looks at the `Default::default()` body in existing `derivable_impls` clippy lint:
https://github.com/rust-lang/rust-clippy/pull/13988
  - Lint against `Bar { .. }.foo.x != Foo { .. }.x`:
https://github.com/rust-lang/rust/pull/135859
Closed, should likely live in clippy as allow-by-default. There's no analogue lint for the same case for `Default`, so either we should have both or neither.
- Restrict `#[non_exhaustive]`:
https://github.com/rust-lang/rust/pull/134539
- Add documentation entry to unstable book:
https://github.com/rust-lang/rust/pull/134855
- Constify `Default::default()` so that it can be used in default field values:
https://github.com/rust-lang/rust/pull/134628
- Propose rustfmt style:
https://github.com/rust-lang/style-team/issues/205
- Add test for privacy rules:
https://github.com/rust-lang/rust/pull/135700
- Disallow `A { .. }` if `A` has no fields:
https://github.com/rust-lang/rust/pull/135703
- Fix lifetime checking ICE:
https://github.com/rust-lang/rust/pull/135711
- Detect APIs with non-exhaustive struct constructors forcing `A { field, .. }` always:
    - https://github.com/rust-lang/rust/pull/135794
    - https://github.com/rust-lang/rust/pull/135846