Tracking issue for RFC 3681: Default field values
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
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:
#[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
- Implement the RFC (cc @rust-lang/compiler)
- Parse the new syntax
- Support
#[derive(Default)]expansion of structs with default field values - Support
#[derive(Default)]expansion of struct variants where every field has a default - Restrict
#[non_exhaustive]on items with default field values - Restrict defaults on tuple struct and tuple variants
- Define visibility of defaulted field values on value construction (
S { .. }is allowed ifainstruct S { a: () }is not visible?) - Restrict
S { .. }whenShas no fields with default values - Lint against explicit
impl Defaultwhen#[derive(Default)]would be ok- Additional lints for iffy cases (maybe belongs in clippy?)
- Adjust documentation (see instructions on rustc-dev-guide)
- Add unstable book entry
- Add to the Reference https://github.com/rust-lang/reference/pull/1766
- Mention in The Book https://github.com/rust-lang/book/pull/4589
- Add example to Rust By Example https://github.com/rust-lang/rust-by-example/pull/1978
- Formatting for new syntax has been added to the Style Guide (nightly-style-procedure) https://github.com/rust-lang/rust/pull/149423
- Stabilization PR (see instructions on rustc-dev-guide)
Unresolved Questions
What is the right interaction wrt.Made mutually exclusive.#[non_exhaustive]?Customization of behavior wrt. visibility rules (allow user to specify that value can be constructed withFollowing RFC: struct can't be constructed with..covering defaulted field that otherwise is not accessible)..if it covers a private field.AllowingDisallowed, can be added later if we find a reason to support that...on types with no default fields, particularly in unit structs?*Allowing the use ofLet's not try that, particularly in the face offield_name: _to specify the use of the default for that specific field?*~const Defaultallowing forfield_name: Default::default()andfield_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 associatedconstand usefield_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
- 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
Defaultimpls that could diverge against default field values:
https://github.com/rust-lang/rust/pull/134441- Only lint for "manual
impl Defaultwithout 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 existingderivable_implsclippy 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 forDefault, so either we should have both or neither.
- Only lint for "manual
- 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
https://github.com/rust-lang/rust/pull/149423 - Add test for privacy rules:
https://github.com/rust-lang/rust/pull/135700 - Add test for use of
#[const_trait] Default:
https://github.com/rust-lang/rust/pull/143649 - Disallow
A { .. }ifAhas 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: - Support parsing in
syn:https://github.com/dtolnay/syn/pull/1851UseType::Verbatimto parse: https://github.com/dtolnay/syn/pull/1870- https://github.com/dtolnay/syn/pull/2054
- Rust-by-Example: https://github.com/rust-lang/rust-by-example/pull/1978
- The Book: https://github.com/rust-lang/book/pull/4589
- Rust Analyzer: https://github.com/rust-lang/rust-analyzer/pull/21408 (https://github.com/rust-lang/rust-analyzer/issues/19780)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the unchecked checklist items and their linked Reference, The Book, Rust By Example, and Style Guide work. Read the rustc-dev-guide documentation and stabilization instructions before choosing a subtask. Done means completing a selected documentation or formatting item and reflecting its status in the tracking issue; stabilization remains a separate step.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers, documentation
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100