Hello.
I try to custom a derive macro (it doesn't meet me) in following way:
let s1 = proc_macro_transform(&mut syn::DeriveInput);
let s2 = my_proc_macro_transform(s1);
proc_macro_transform is the origin proc_macro, and my_proc_macro_transform is what I want.
But when I try to export proc_macro_transform from its crate. I meet:
error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
So I guess proc_macro_transform and my_proc_macro_transform are functions in your proc-macro crate? And you want to export them like pub fn my_proc_macro_transform? If that's the case that isn't possible and you need a second, non-proc-macro crate to export these functions. You can then re-export your derive macro from the non-proc-macro crate. This is a common pattern, the most famous example being serde and serde_derive (the derive suffix is usually used for the proc-macro crate providing the derive macros for the items exported by the other crate).
Thanks for your help. proc_macro_transform is defined in a third-party proc_macro crate. my_proc_macro_transform is defined in a proc_macro crate written by me. And I want to export proc_macro_transform, and use it in my proc_macro crate.
Well, serde_derive doesn't export it. the de module is private. Note that it couldn't export it in the first place because expand_derive_deserialize is a function and not a procedural macro.
error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
I guess you could create a wrapper similar to the Deserialize macro but not as a derive macro but a function-like one and export that (from your fork of serde_derive) instead of the function directly:
#[proc_macro]
pub fn expand_derive_deserialize(input: TokenStream) -> TokenStream {
let mut input = parse_macro_input!(input as DeriveInput);
de::expand_derive_deserialize(&mut input)
.unwrap_or_else(syn::Error::into_compile_error)
.into()
}
Then you can call it in your macro as:
[proc_macro_derive(UntaggedDeserialize, attributes(serde))]
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
- let mut input = parse_macro_input!(input as DeriveInput);
- let s1 = serde_derive::de::expand_derive_deserialize(&mut input)
- .unwrap_or_else(syn::Error::into_compile_error)
- .into()?;
+ let s1 = serde_derive::expand_derive_deserialize!(input);
Never tried this though, might not work as I wish it would because the input token stream is not expanded?
Edit: After thinking about it, the exporting-a-function-like-procedural-macro is probably not going to work, but if you don't need the Deserialize and Serialize macros in your serde_derive fork, you should be able to make your fork into a normal crate by removing this line and export serde_derive::de::expand_derive_deserialize.