I am trying to use mongodb library which has a lot of non_exhaustive structs and compiler fails to compile when I do
let options = UpdateOptions{
upsert:Some(true),
..Default::default()
}
however
let mut options = UpdateOptions::default();
options.upsert=Some(true)
compiles just fine.
Since if struct T implements default all its fields must also implement default so I am failing to understand the difference between these 2 versions.
The struct update syntax, aka functional update syntax, cannot be used for non-exhaustive structs.
It isn't anything to do with the Default trait specifically; what you were trying to do was to create a temporary UpdateOptions using Default::default(), and then using the struct update syntax to move the values from the temporary into your new struct. You could use ..variable too. In particular, the syntax doesn't call Default::default() on all the fields or anything like that.
Since if struct T implements default all its fields must also implement default
That's also not true incidentally. If a struct TderivesDefault, all it's fields must also implement Default. But it can implementDefault even if its fields do not.
thanks for the answer It clarified things a lot better and it is really unintuitive that they designed it this way in my opinion.
If anyone has similar issues I've written a small macro to get over this issue
Yeah, pretty much nobody expects FRU to work the way it does. Unfortunately we looked at changing it and it's a breaking change because of some corner cases.
Incidentally, that thread also has a macro that might interest you, as it's very similar to the one you wrote but also magically allows not specifying the type: