rust-derive-builder
rust-derive-builder copied to clipboard
generic fields cannot be defaulted (or skipped)
#[derive(Builder)]
struct Generic<T> {
#[builder(setter(skip))] // <-- implicit default
pub ipsum: T,
#[builder(default)] // <-- explicit default
pub dolor: T,
}
fails with
error[E0277]: the trait bound `T: std::default::Default` is not satisfied
|
| #[derive(Builder)]
| ^^^^^^^ the trait `std::default::Default` is not implemented for `T`
= help: consider adding a `where T: std::default::Default` bound
= note: required by `std::default::Default::default`
The reason is that we never emit bounds like T: Default
(cmp. #91)
Current workarounds are:
- add a
T: Default
bound on the target type (e.g.struct Generic<T: Default>
) - use a custom default
#[builder(default="magic_generic_fn_in_scope()")]
I looked at this when fixing #91, but I couldn't find a way to express "this is fine if a) a struct-level default was specified, b) an explicit field-level default was specified, or c) this field was set explicitly at runtime" which made me suspect it's not possible to handle ergonomically through the type system.
This is even worse when we have something like:
Generic<T> {
list: Vec<T>
}
Where for certain cases I know T
does not implement Default
, so I can't enforce it, however obviously Vec<T>
does... For such generic types, I can not even use the builder.
Using an explicit default seems like a simple enough workaround that we don’t need to keep this issue open.