Responding en masse; no individual part of this response is directed towards a particular user unless someone is directly mentioned.
NB: I have not updated the pre-RFC since its posting. I am discussing what should happen before updating the text, which takes a fair amount of time and effort.
After reading all responses, I am leaning further in favor of the Foo { .. }
style initialization present in Centril's RFC and will be responding as such. I suggest others follow suit as that's the direction I'm headed. The RFC text will be updated once there is general agreement on the main principles.
My current intention is to have the default field value be semantically the same as a const
block, such that control flow is not supported, everything must be in scope, and the expression is type-checked against the declared field type. With Foo { .. }
construction, there is no concern about the expression potentially being dead code. The requirement to be a const
context implicitly prohibits async
code, though I suppose a block_on
call could potentially be supported in const
contexts in the future.
With regard to the discussion of how to support different defaults for different derives: why? What situation would necessitate a field to have a different default value depending on what is being derived? And is this a use case we want to encourage, or is is requiring manual implementations or an attribute macro in such a situation (as is the status quo) preferable?
For syn
supporting this syntax, it's unfortunate that the library doesn't appear to be forward compatible in this situation. That said, I don't believe we should be making decisions about what to include in a language primarily on the reason that a library can't support it, particularly when said library is capable of creating a breaking release while the language cannot (barring edition-related things). This wouldn't be the first syntax introduced that syn
is incapable of handling, as #[foo = expr]
currently cannot be parsed. While certainly relevant to the topic at hand, how crates such as syn
, serde
, etc. would handle the transition (if any) from existing attributes to built-in syntax doesn't seem related to the RFC. Examples are provided in the RFC as to what would theoretically be possible, not what the crates must or even should do; it's a decision for those crates to make on their own.
The syntax for default field values and #[derive(Default)]
using them need to land on stable (but not necessarily nightly) at the same time. If syntax lands first, it would be a breaking change to implement the others. Foo { .. }
construction would not need to land at the same time. That's why changes to #[derive(Default)]
are (and will continue to be) included in the RFC.
One thing I thought of that is not covered in Centril's RFC is that construction of structs where there are private fields (or where the struct is non-exhaustive) is that there needs to be a way to guarantee that future fields have a default value (for external users). I'm not sure what form this should take, so ideas are welcome.