Skip to content

Conversation

@DJMcNab
Copy link

@DJMcNab DJMcNab commented Jan 5, 2026

This PR incorporates work from @estebank in #1851. See also rust-lang/rust#132162 (comment) for context; this is the PR for "solution 2", to unblock the language feature.

Fixes #1774

#[derive(Default)]
struct Pet {
    name: Option<String>,
    age: i128 = 42,
    //        ^^^^
}

By running cargo-semver-checks --all-features (v0.45.0), I have confirmed that this is not a breaking change.

This PR has two related changes:

  1. It exposes FieldWithDefault, which is a version of Field, with the addition of the optional default field. This is then used to create a parallel hierarchy of all Syn types, with the same naming pattern. That is, it also creates FieldsNamedWithDefault, FieldsWithDefault, VariantsWithDefault, DataStructWithDefault, etc.
  2. The parsing for this is shared with Field, to allow for as much shared code as possible. There is one subtle change here; the parsing for Field (and therefore FieldsNamed, Fields, DeriveInput, etc.) will now ignore any default value provided (i.e. not give an error, but also not reflect it in the AST). This enables a silent upgrade of most derive macros to support their same codegen as if the default field values didn't exist, which will be extremely valuable in the ecosystem.

This is explicitly not #1911; instead, that issue would likely be updated to mean "revert this PR, and land #1851 as part of v3.x".

The new structs in this PR is not behind a feature flag. This is because the current infrastructure in syn-internal-codegen only supports "any" style feature flags, whereas this would need to be handled as "all" style feature flags.
I'm not going to make the changes to the codegen infrastructure myself. I would move these types behind feature flags if:

  • You say that you want this code to be in its own modules (and therefore under two feature flags); OR
  • You provide the patches to the infrastructure which means it supports the "all" style flags.

The silent ignoring of the default values would definitely be reasonable to object to. I think it's the least bad option on an ecosystem level, but I'm happy to change it (either some form of logging, or just throwing an error).

The parallel hierarchy is not complete. That is, we do not support structs with default field values inside blocks (i.e. inside functions/block expressions/etc.). That's because it requires changing so much more code. (But obviously if they exist, they'll be silently ignored).

A reasonable alternative would be to implement #1870 for those nested fields.

This is exposed as a version of the structures with a
`WithDefault` suffix, as the simpler solution has
been ruled out.

Co-Authored-By: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
@nik-rev
Copy link

nik-rev commented Jan 14, 2026

Suggestion: Rather than having unique names for these v2 types, they could exist in a separate module and retain their name.

The primary motivation behind this is that it will be easier for people to migrate to supporting default field values, with a simple change:

-use syn::Variants;
+use syn::with_default::Variants;

And they won't have to do much else besides fixing the unhandled fields.

Once syn v3 comes, they can switch back:

-use syn::with_default::Variants;
+use syn::Variants;

Imagine if instead the type names were different. You'd first have to rename every type, then you'd have to rename them back

Rename table

current suggested
FieldWithDefault with_default::Field
FieldsNamedWithDefault with_default::FieldsNamed
FieldsWithDefault with_default::Fields
VariantsWithDefault with_default::Variants
DataStructWithDefaul with_default::DataStruct
DeriveInput with_default::DeriveInput

@DJMcNab
Copy link
Author

DJMcNab commented Jan 14, 2026

It's plausible, and it does have appealing properties. I don't particularly want to spend much more time working on this without David's input, however.

@estebank
Copy link

Gentle ping @dtolnay, in case you can quickly comment on the above open question even if you don't have the time to perform a full review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parse default values in fields

3 participants