Skip to content

Conversation

@DJMcNab
Copy link

@DJMcNab DJMcNab commented Jun 12, 2025

See #1774 (noting that a true fix will require 3.x and #1851)

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

Adapted from #1851. cc @estebank

This PR is an alternative to #1851 but avoiding the breaking-change. Instead, if a named field has a default value, the field's entire type and the default value is parsed as a Type::Verbatim. Our users can then detect and support this case, by re-parsing the verbatim type into the type and default value expression.

Semantically of course, the default value is not part of the type, but syntactically, the default value is in type position. Our handling of negative inherent impls has a similar shape.

The interaction with unnamed_fields was a bit unclear to me, so I took my cue from #1851 (of allowing both features to be combined). Note that since rust-lang/rust#131045, unnamed_fields is not supported by upstream Rust.

I chose not to implement the solution you proposed in #1851 (comment), both because the idiomatic implementation strategy was unclear to me, and because if I understand correctly, the proposed solution makes supporting default_field_values in dependent macros unfeasible.

Thanks for all your great work!

Adapted from dtolnay#1851.

Co-Authored-By: =?UTF-8?q?Esteban=20K=C3=BCber?= <[email protected]>
vis: Visibility::Inherited,
ident: Some("field"),
colon_token: Some,
ty: Type::Verbatim(`i32 = 42`),
Copy link

@Veetaha Veetaha Jun 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a bearable hack. Although I do forsee that existing proc macros will still break if they encounter the default field value syntax, this makes it easier to hackily get the default expression from the type for macros that want to start supporting this syntax (and I would be interested in that too with bon).

An alternative way to approach this could be to add a new syn::Item variant with versioning applied e.g. syn::Item::StructV2(StructV2) where StructV2 is the same as the current Struct but with the additional default field. Although, this would also necessitate the FieldV2 struct and bloating the crate with lots of similar/but-slightly-different types. This idea seems crazy, but IDK, just wanted to state it here, and maybe someone could be inspired with it

@jplatte
Copy link

jplatte commented Aug 5, 2025

Gentle ping, @dtolnay

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.

3 participants