Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/struct_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ impl<'a> StructInfo<'a> {
quote!(#[doc(hidden)])
};

let mut b_decl_generics = b_generics.clone();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this required? b_generics is only used when declaring the builder type (and you want the default there) and when splitting it for the impl block (where defaults should not be looked at anyway). So why clone it instead of modifying the original?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's redundant, indeed.

for param in &mut b_decl_generics.params {
if let syn::GenericParam::Type(ref mut param) = param {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this match all type parameters? The one you want to add a default to is always the first one, so you can just modify that.

Or even better - just add the default when creating b_generics.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that would match all parameters. I guess that barely make sense.

Though unfortunately rust doesn't allow to specify defaults for non-trailing generics and the TypedBuilderFields is the first one. I'm not sure whether it's fine to set it as the last one, perhaps it might break some code.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm half minded to just go with your original design as a temporary solution. Once const generics support strings I plan on doing a great refactor that'll break anything (other than regular by-the-book usage) anyway, and once that come I may remove it in favor of something else.

param.default = Some(empties_tuple.clone().into());
}
}

let (b_generics_impl, b_generics_ty, b_generics_where_extras_predicates) = b_generics.split_for_impl();
let mut b_generics_where: syn::WhereClause = syn::parse2(quote! {
where TypedBuilderFields: Clone
Expand All @@ -149,7 +156,7 @@ impl<'a> StructInfo<'a> {
#[must_use]
#builder_type_doc
#[allow(dead_code, non_camel_case_types, non_snake_case)]
#vis struct #builder_name #b_generics {
#vis struct #builder_name #b_decl_generics {
fields: #all_fields_param,
phantom: (#( #phantom_generics ),*),
}
Expand Down
1 change: 1 addition & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ fn test_builder_name() {
#[derive(TypedBuilder)]
struct Foo {}

let _: FooBuilder = Foo::builder();
let _: FooBuilder<_> = Foo::builder();
}

Expand Down