Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code cleanup. Make build method generate as const #123

Closed
wants to merge 6 commits into from

Conversation

DanikVitek
Copy link

  • Add #![forbid(rust_2018_idioms)] to the typed-builder-macro crate
  • Make the builder function const when possible

@@ -52,7 +52,7 @@ impl ApplyMeta for MutatorAttribute {
}

impl Parse for Mutator {
fn parse(input: ParseStream) -> syn::Result<Self> {
fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
Copy link
Owner

Choose a reason for hiding this comment

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

This seems redundant. Is this because of that #![forbid(rust_2018_idioms)] thing?

Copy link
Author

Choose a reason for hiding this comment

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

Yes. This lets to see at a glance where a borrowing occurs

@@ -16,7 +18,7 @@ pub struct StructInfo<'a> {
pub vis: &'a syn::Visibility,
pub name: &'a syn::Ident,
pub generics: &'a syn::Generics,
pub fields: Vec<FieldInfo<'a>>,
pub fields: Box<[FieldInfo<'a>]>,
Copy link
Owner

Choose a reason for hiding this comment

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

Was this really necessary?

Copy link
Author

Choose a reason for hiding this comment

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

Well, it is not very usefull, but the field is effectively immutable and so there is no need to take away additional 8 bytes for capacity. But the struct is already >2KiB in size so tbh no much difference

},
)
});
let builder_method_const = Rc::new(OnceCell::new());
Copy link
Owner

Choose a reason for hiding this comment

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

Respectfully WTF? Looking at the code, it seems like a simple:

let mut builder_method_const = true;

would suffice.

Copy link
Author

Choose a reason for hiding this comment

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

Borrow checker was not happy about the moved value. It could be done with Rc<Cell<bool>> though.

Copy link
Owner

Choose a reason for hiding this comment

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

I tried it locally and it worked. Had to remove the move from the closure in the map, of course.

I speculate that it didn't work for you because you tried it before adding the collect. The compiler, in a way, was complaining about the very same bug that the collect solved.

Another option is to just do a second iteration:

let builder_method_const = self
    .included_fields()
    .filter_map(|field| field.builder_attr.via_mutators.as_ref())
    .all(|via_mutators| matches!(via_mutators.init, syn::Expr::Lit(_)))
    .then(|| quote!(const));

But of course - all of this is irrelevant because #123 (comment).

typed-builder-macro/src/struct_info.rs Show resolved Hide resolved
|| quote!(()),
|via_mutators| {
let init = &via_mutators.init;
if !matches!(init, syn::Expr::Lit(_)) {
Copy link
Owner

Choose a reason for hiding this comment

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

I like to make things explicit. If the build method is to be const, it should be marked as such in the configuration attributes - not implicitly deduced based on some incomplete (literals aren't the only const expressions) heuristics.

Copy link
Author

Choose a reason for hiding this comment

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

True, makes sense. It was just my compulsive thought to make it const when I saw the macro expansion for my usecase. But now I know that it is not so simple

@idanarye
Copy link
Owner

Given how the setter methods are not const, and the build method is not const, is it really useful to make the builder method const?

@@ -70,7 +72,7 @@ impl<'a> StructInfo<'a> {
})
}

pub fn builder_creation_impl(&self) -> Result<TokenStream, Error> {
pub fn builder_creation_impl(&self) -> syn::Result<TokenStream> {
Copy link
Owner

Choose a reason for hiding this comment

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

TBH this is the only change I like in this PR.

@DanikVitek
Copy link
Author

Given how the setter methods are not const, and the build method is not const, is it really useful to make the builder method const?

Not really. I'm not sure if it would be possible because of deconstruction of self. Currently it's not possible in const fn afaik

@idanarye
Copy link
Owner

Once rust-lang/rust#67792 gets stabilized, builder, build, and all the setters could be const - and that would be controlled via a flag on the attribute (#84). Until then, I see no point in making only the builder method const.

@DanikVitek DanikVitek closed this Oct 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants