When you add a new field to a struct, usually you would want compilation errors in all places where there isn’t already a clear (and intentional) way of initializing the field. When using ..Default::default(), you already give up some of this, these initializations will keep compiling, but at least, it should still be sensible behavior in most cases.[1] However, if your proposed .. happens to make use of a variable that just happens to have the same name of the newly added field, it’s quite often not intended behavior - so you would have introduced a bug into your program during the refactor, and the compiler never pointed you to the use-site of your struct that would’ve needed to be updated.
So to answer the question, I’d say ultimately it’s a design decision. There’s nothing technical hindering Rust from implementing such a feature, but to me it feels not in line with the usual explicitness, and it can have negative consequences as outlined above. For example, if I recall correctly (edit: here’s the docs), Haskell (or at least GHC) does offer such a version of its “functional update” syntax, where the fields are implicitly taken from corresponding variables in scope. Interestingly, to be analogous to the Haskell feature, if the MyStruct { x: 2, .. }expressionreads all other fields by their name from variables in scope, then the MyStruct { x: 2, .. }pattern would also need to introduce variables for all unmentioned fields. (Which it doesn’t, and we cannot simply change that, so that may be another argument against having such a feature with the exact syntax you proposed.)
I see, the conflict between struct initialisation and pattern matching clause did cross my mind, but thought it would be easy to treat those separately. On a second thought, its true it would not be a very good design choice to have the same syntax with different behaviours.
To me, the first argument was enough to realise why this would not be ideal! Thanks!
I feel like there is also a readability issue here: looking at
MyStruct {
x: 2,
..
}
all by itself, it seems to me people would expect this to mean something like, perhaps exactly the same as, your first case, with ..Default::default().
I've been procrastinating on it, but I do want to push on this. I did sneak parser support for part of this feature, and was thinking about adding more support for the feature purely as a way to produce more accurate diagnostics (tell you to use impl Default when it could be done only). I lean this way because it is a "cheap" way of exercising the feature without having us commit to a specific behavior before actually evaluating real behavior against a wider set of examples (which might uncover problems not yet mentioned in that thread).