How does procedural macro do in the low level?

From rust's documentation, I know that procedural macro can be thought of as an AST to AST mapping, and I want to know how does it do in the low level.

More specifically:

  • Is a proc-macro lib a dynamically linked library?
  • Does it dynamically linked to rustc in the compiler time?

I don't think Rust makes any guarantees about this. Specifically, proc macro crates are:

  • compiled to the host architecture (not the target architecture)
  • compiled before the crate they are used in
  • called at compile-time for the crate they are used in

However, nothing is guaranteed about whether this is done as a dynamic library, or a separate process, or some other mechanism. The documentation and even the reference go out of their way to leave this unspecified.

I looked for information on the current implementation, but I couldn't find anything easily accessible. The rustc-dev-guide touches on them briefly, but does not say anything about how the proc macros are actually called (besides the fact that it uses a #[repr(C)] interface). It seems highly likely that it uses a dynamic library, but I couldn't find the code which confirms it.

This pull request from 2018 looks promising. From the comments, it looks like before that PR proc macros were definitely dynamically linked. I think the status after that PR is that proc macros are statically linked in or compiled with some compiler internals, and then that binary is dynamically linked to the compiler (and communicated to only through a C interface). However, I didn't read the full code, and that's mostly my guessing.

Someone with more knowledge of what the compiler does now would be able to answer this better. I can at least tell you that the answer wasn't easy to find, though. And when we do find what the compiler does now, there are no guarantees it continues to do that in the future.

1 Like

There's a plan to distribute precompiled proc macros as a WASM format. For now, check this repository for the in-depth explanations.

1 Like

Fair! If it becomes a compiler option, though, I would definitely expect it to be opt-in to keep compatibility.

The current reference does specify that proc macro type crates are compiled for "the same target the compiler itself was built with": https://doc.rust-lang.org/reference/linkage.html?highlight=crate-type#linkage

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.