Pre-RFC: User-provided default field values

You know what, I’ve change my opinion. Explicit marking seems rather beneficial both as

  • a way to opt-out of Foo { a, b } construction in a struct where all fields are public (i.e. as a way to avoid the pub(crate) _marker: () = () workaround)
  • a way to opt-in to usage of Foo { a, .. } in a struct that has some private fields (in order to avoid any possible confusion/mistake if someone adds default values to those fields just with the intention of either using a custom value for the derive(Default) implementation, or in order to use .. internally)

I would personally propose that the new marker would simply be a .. in the struct declaration itself. I.e.

pub struct Foo {
    pub a: u32,
    pub b: u32,
    ..
}

would no longer permit initialization with Foo { a, b } outside of the current crate (only Foo { a, b, .. } allowed), and

pub struct Bar {
    pub a: u32,
    b: u32 = 0,
}

would not allow initialization as Foo { a, .. } outside of the current module (due to the visibility of b), unless you change the declaration to

pub struct Bar {
    pub a: u32,
    b: u32 = 0,
    ..
}

Both could render nicely in rustdoc, too, the latter could just render as

pub struct Bar {
    pub a: u32,
    ..
}

because the private fields don’t matter in the documentation.


Adding the .. marker to a struct with private fields without default value results in a compilation error.

This also means, it becomes impossible to accidentally break API by adding a private field without default value.

5 Likes