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

Marker attributes #261

Merged
merged 4 commits into from
Dec 30, 2021
Merged

Marker attributes #261

merged 4 commits into from
Dec 30, 2021

Conversation

Desdaemon
Copy link
Contributor

@Desdaemon Desdaemon commented Dec 30, 2021

Resolves #260.

Only the attribute macro itself is implemented, not any mechanism to retrieve information from the attributes.

Some bike-shedding:

  • Name of the attribute, currently frb.
  • Should it be visible to users by default? (currently no). This boils down to convenience vs. compile times, due to the added compile-time dependency on syn.

@fzyzcjy
Copy link
Owner

fzyzcjy commented Dec 30, 2021

Name of the attribute, currently frb.

Agree ;)

Should it be visible to users by default? (currently yes). This boils down to convenience vs. compile times, due to the added dependency on syn.

Why do we add dependency on syn? Since the proc macro itself does nothing in it, what about implementing a "raw" proc macro?

@fzyzcjy
Copy link
Owner

fzyzcjy commented Dec 30, 2021

What about this: let the frb macro does nothing inside that proc macro function body. Instead, simply output the input. Then no need for syn, and that fn frb() {} will almost be empty function.

@Desdaemon
Copy link
Contributor Author

Why do we add dependency on syn? Since the proc macro itself does nothing in it, what about implementing a "raw" proc macro?

It's needed to remove the attributes from the AST, as rustc does not accept attribute macros on fields. (Only derive macros are allowed to have field attributes.)

@Desdaemon
Copy link
Contributor Author

Desdaemon commented Dec 30, 2021

and that fn frb() {} will almost be empty function.

Also yes, the macro does little to no work if it's not used on a struct/enum/union.

@fzyzcjy
Copy link
Owner

fzyzcjy commented Dec 30, 2021

Hmm interesting... Can we do it without syn dependency?

@Desdaemon
Copy link
Contributor Author

Hmm interesting... Can we do it without syn dependency?

I've never tried this, it does seem a lot more effort upfront though. What we could do is re-implement a subset of syn's features, but of course we'd still be depending on the parsing functionality of syn which is only a fraction of the code.

@fzyzcjy
Copy link
Owner

fzyzcjy commented Dec 30, 2021

Hmm interesting... Can we do it without syn dependency?

I've never tried this, it does seem a lot more effort upfront though. What we could do is re-implement a subset of syn's features, but of course we'd still be depending on the parsing functionality of syn which is only a fraction of the code.

Interesting... Then we should not do that.

Should it be visible to users by default? (currently yes).

Then this becomes a question

@Desdaemon
Copy link
Contributor Author

Related: rust-lang/rust#65823

@Desdaemon
Copy link
Contributor Author

Given that this is a new feature with no real use cases yet, I think we can keep it gated behind a feature for now (already done), and we can reassess this need later on.

@fzyzcjy
Copy link
Owner

fzyzcjy commented Dec 30, 2021

btw is there a crate that we can use directly, instead of manually writing down those calls to remove_marker_attr? seems like this should be a commonly used situation

@fzyzcjy
Copy link
Owner

fzyzcjy commented Dec 30, 2021

going to merge it and publish it and change CI soon

@Desdaemon
Copy link
Contributor Author

FWIW the last commit shaved off about 2 seconds on a debug clean build, so I'm hopeful it's not too much of an impact.

@Desdaemon
Copy link
Contributor Author

btw is there a crate that we can use directly, instead of manually writing down those calls to remove_marker_attr? seems like this should be a commonly used situation

I'm quite sure frb_codegen has no use for these, as they are only there to satisfy rustc? Anyways I can move them later if needed.

@fzyzcjy
Copy link
Owner

fzyzcjy commented Dec 30, 2021

I'm quite sure frb_codegen has no use for these, as they are only there to satisfy rustc? Anyways I can move them later if needed.

I mean these

pub fn frb(_: TokenStream, item: TokenStream) -> TokenStream {
if let Ok(mut input) = syn::parse::<DeriveInput>(item.clone()) {
input.data = match input.data {
Data::Struct(mut st) => {
st.fields = remove_marker_attr_from_fields(st.fields);
Data::Struct(st)
}
Data::Enum(mut enu) => {
enu.variants = enu
.variants
.into_iter()
.map(remove_marker_attr_from_variant)
.collect();
Data::Enum(enu)
}
Data::Union(mut uni) => {
uni.fields = remove_marker_attr_from_named_fields(uni.fields);
Data::Union(uni)
}
};
quote! { #input }.into()
} else {
item
}
}
fn remove_marker_attr_from_variant(mut variant: Variant) -> Variant {
variant.fields = remove_marker_attr_from_fields(variant.fields);
variant
}
fn remove_marker_attr_from_field(mut field: Field) -> Field {
field.attrs = field.attrs.into_iter().filter(is_marker_attr).collect();
field
}
fn remove_marker_attr_from_named_fields(mut fields: FieldsNamed) -> FieldsNamed {
fields.named = fields
.named
.into_iter()
.map(remove_marker_attr_from_field)
.collect();
fields
}
fn remove_marker_attr_from_fields(fields: Fields) -> Fields {
match fields {
Fields::Named(fields) => Fields::Named(remove_marker_attr_from_named_fields(fields)),
Fields::Unnamed(mut fields) => {
fields.unnamed = fields
.unnamed
.into_iter()
.map(remove_marker_attr_from_field)
.collect();
Fields::Unnamed(fields)
}
_ => fields,
}
}

is there someone already write down a crate called, e.g. "create_proc_macro_that_does_nothing" on crates.io and we can use that

@fzyzcjy
Copy link
Owner

fzyzcjy commented Dec 30, 2021

FWIW the last commit shaved off about 2 seconds on a debug clean build, so I'm hopeful it's not too much of an impact.

Agree. not a big problem

@Desdaemon
Copy link
Contributor Author

is there someone already write down a crate called, e.g. "create_proc_macro_that_does_nothing" on crates.io and we can use that

Strangely enough, I couldn't find anything like that, the closest thing was wasm_bindgen itself which uses more features of syn.

@fzyzcjy
Copy link
Owner

fzyzcjy commented Dec 30, 2021

interesting. so let me merge it

I may not have time immediately and will publish tomorrow (ping me if I forget)

@fzyzcjy fzyzcjy merged commit 873a3c8 into fzyzcjy:master Dec 30, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Marker attributes
2 participants