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

refactor derive - oliver #59

Closed
wants to merge 3 commits into from
Closed

refactor derive - oliver #59

wants to merge 3 commits into from

Conversation

ghost
Copy link

@ghost ghost commented Feb 8, 2021

Currently this approach fails with the following compiler error:

   Compiling gfp-derive v0.1.0 (/media/oliver/WD/generic-field-projection/derive)
error[E0308]: mismatched types
   --> derive/src/lib.rs:197:5
    |
196 |   ) -> proc_macro::TokenStream {
    |        ----------------------- expected `proc_macro::TokenStream` because of return type
197 | /     item!(
198 | |         unsafe impl #generic_header ::gfp_core::Field for #ident<super::#input_ident #generic> {
199 | |             type Parent = super::#input_ident #generic;
200 | |             type Type = #ty;
...   |
211 | |         }
212 | |     )
    | |_____^ expected struct `proc_macro::TokenStream`, found enum `syn::Item`
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
   --> derive/src/lib.rs:298:23
    |
298 |           contents.push(gen_header(
    |  _______________________^
299 | |             generic_header,
300 | |             ident,
301 | |             input_ident,
302 | |             generic,
303 | |             ty,
304 | |         ));
    | |_________^ expected enum `syn::Item`, found struct `proc_macro::TokenStream`

error[E0308]: mismatched types
   --> derive/src/lib.rs:419:23
    |
419 |           contents.push(gen_header(
    |  _______________________^
420 | |             generic_header,
421 | |             ident,
422 | |             input_ident,
423 | |             generic,
424 | |             ty,
425 | |         ));
    | |_________^ expected enum `syn::Item`, found struct `proc_macro::TokenStream`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0308`.
error: could not compile `gfp-derive`

derive/src/lib.rs Outdated Show resolved Hide resolved
@RustyYato
Copy link
Owner

This looks good! If you find something else that's duplicated like this can you de-duplicate it?

@ghost
Copy link
Author

ghost commented Feb 8, 2021

Yes I spotted several other clear opportunities to simplify the module constructions.

@ghost ghost requested a review from RustyYato February 8, 2021 19:58
@ghost ghost mentioned this pull request Feb 8, 2021
@RustyYato RustyYato linked an issue Feb 8, 2021 that may be closed by this pull request
@RustyYato RustyYato added the enhancement New feature or request label Feb 8, 2021
Copy link
Owner

@RustyYato RustyYato left a comment

Choose a reason for hiding this comment

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

I think I should have been more clear, if you find any pieces of code that are mostly duplicated across multiple places with only a small amount of variation, then extract that out to a function.

For example gen_header takes some code that was duplicated twice, and extracts it out. However, gen_header_unnamed just shifts some code around.

One other place that could benefit from extraction:

for field in fields.named {
let ident = field.ident.unwrap();
contents.push(item!(
#[allow(non_camel_case_types)]
pub struct #ident<T>(::gfp_core::derive::Invariant<T>);
));

for (i, field) in fields.unnamed.iter().enumerate() {
use syn::spanned::Spanned;
let ident = quote::format_ident!("_{}", i, span = field.span());
contents.push(item!(
#[allow(non_camel_case_types)]
pub struct #ident<T>(::gfp_core::derive::Invariant<T>);
));

for field in fields.named {
let ident = field.ident.unwrap();
contents.push(item!(
#[allow(non_camel_case_types)]
pub struct #ident<T>(::gfp_core::derive::Invariant<T>);
));

These for loops are very similar, with only a few minor differences between them. If you can find a way to unify them, that would be incredible.

merge_imports = true
imports_granularity = "Crate"
Copy link
Owner

Choose a reason for hiding this comment

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

What's the difference between these two? I'm not too familiar with rustfmt config

Copy link
Author

Choose a reason for hiding this comment

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

this was the suggested resolution to a cli warning

Comment on lines +214 to +221
fn gen_header_unnamed(
generic_header: &syn::ImplGenerics,
ident: &syn::Ident,
input_ident: &syn::Ident,
generic: &syn::TypeGenerics<'_>,
ty: &&syn::Type,
index: &syn::Member,
) -> syn::Item {
Copy link
Owner

Choose a reason for hiding this comment

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

If a function is only called once, then it doesn't pull its weight.

}

// `TokenStream` construction for `derive_struct()` and `derive_named()`
fn token_fields(
Copy link
Owner

Choose a reason for hiding this comment

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

same as above

}

// `TokenStream` construction for `derive_unnamed()`
fn token_fields_unnamed(
Copy link
Owner

Choose a reason for hiding this comment

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

same as above

}

// `TokenStream` construction for `derive_union()`
fn token_fields_union(
Copy link
Owner

Choose a reason for hiding this comment

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

same as above

@ghost
Copy link
Author

ghost commented Feb 8, 2021

I think the only marginal benefit to functions holding macro code are the type signatures for all of the elements.

It's interesting to learn it should be possible to harmonize all of these only slightly differing macros contents, so I'll look into doing that and refactor these properly.

Thanks for the review!

@RustyYato
Copy link
Owner

To me, that's not enough of a benefit to justify extracting it to a function. However, if you think it makes the code easier to follow, hopefully, it will make it easier to get new contributors like yourself!

@ghost
Copy link
Author

ghost commented Feb 8, 2021

I agree with you about it, though yes I think there are some benefits to code readability having the types shown. If I can get the refactor done properly it shouldn't be an issue.

@RustyYato
Copy link
Owner

Hey @kw-fn, are you still working on this PR? If you're busy that's OK, I just want an update.

@ghost
Copy link
Author

ghost commented Feb 25, 2021

I have just been distracted with other projects, I hope to make progress this weekend

@RustyYato
Copy link
Owner

Ok, thanks for the update!

@ghost
Copy link
Author

ghost commented Mar 6, 2021

Looking at this right now! 🍰

@ghost ghost closed this by deleting the head repository Mar 5, 2023
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Refactor derive
1 participant