watt icon indicating copy to clipboard operation
watt copied to clipboard

`cargo watt` subcommand

Open jakobhellermann opened this issue 5 years ago • 2 comments

I made a cargo subcommand called cargo watt, which aims to improve the tooling listed in the README.

Currently, it does two things:

  1. Compile a proc-macro crate (locally, from git or from crates.io) and generate a crate which exposes the compiled wasm
  2. Verify that that wasm file was compiled from some source

Initially I wanted to replace

#[proc_macro]
pub fn the_macro(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    /* ... */
}

with

#[no_mangle]
pub extern "C" fn the_macro(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
    the_macro_inner(input.into().into()
}
pub fn the_macro_inner(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    /* ... */
}

but that doesn't work because Into<proc_macro::TokenStream> does not exist in wasm.

So my solution was to just replace the TokenStreams and hope for the best, while also using a patched version of syn which basically just has all instances of proc_macro replaced with proc_macro2.

This actually works for quite a few crates (e.g. serde-derive, typed-builder, tracing-attributes) but it doesn't for some other ones (everything depending on synstructure and some others).

Now I am wondering: Is it fundamentally impossible to provide the From-impls because proc-macro just doesn't exist in wasm, or would it be possible to do this transformation in some other way?

jakobhellermann avatar May 21 '20 15:05 jakobhellermann

Nice!

Yeah proc_macro::TokenStream can't exist except inside code built with --crate-type proc-macro. That is why proc-macro2 exists.

dtolnay avatar May 21 '20 17:05 dtolnay

I see. I assume it is not possible to [patch] proc-macro itself? Then I guess search+replace and hope for the best is the best approach for cargo watt.

jakobhellermann avatar May 21 '20 17:05 jakobhellermann