Is there a specific reason meta programming is often done in build scripts instead of proc macros? I keep seeing code like this:
include!(concat!(env!("OUT_DIR"), "/settings.rs"));
With that, I miss rust-analyzer's ability to expand the macro and I don't see the advantage. (except maybe that proc macros need a little bit more setup?)
Maybe I'm just missing some tip how to work with this efficiently?
It's largely a simplicity and debuggability issue: for example, at least with ISLE (which also is integrated in this way), we can separately invoke the metacompiler to see plain old source code in files. proc-macros deal with internal token trees and are much much harder to observe because of that
(there's also history at least with ISLE of having checked in the source to the tree, at one point; it's not possible to make such a switch if the thing is based on a proc macro, AFAIK)
In the case of ISLE especially there's also the issue that the set of dependencies needed to build a proc macro takes quite a while to compile, and we've tried to minimize build time for Cranelift.
that makes sense, thanks!
Hm wait but the compile time of a build script vs a proc macro doesn't matter? Also for separate dependencies there's no difference? In that both build scripts and proc macros can have deps and can run in debug mode?
I'm not actually sure of any reason to use a build script over a proc macro other than one was slightly more natural to write
I just meant that there's a lot more code to compile in the sym
family of crates than there is if you just use writeln!
a bunch.
Proc macros don't require syn
(which I think you mean over sym
?) though, we're generating Rust code today and we can convert that to a proc macro with the_string.parse().unwrap()
, no syn
needed
That is what I meant, yeah. Huh, I didn't realize parsing from a string was an option.
if rust-analyzer doesn't support build scripts but does support proc macros then I would say we should probably transition everything to proc macros instead, basically just converting build.rs
to a cranelift-codegen-macros/src/lib.rs
with a little extra fluff
If I may chime in. I think rust-analyzer supports include!
statements fine, but support for it might be pretty recent. After this issue was solved just a couple weeks ago https://github.com/rust-lang/rust-analyzer/issues/3767, I've had no issues with the current approach. I get docs on hover for all generated cranelift code and even jump to definition works properly
Can confirm, I now get docs on hover, can expand the macro... I suspect a reload of vscode fixed it. That editor has a tendency to get confused. Didn't know rust-analyzer could do that, thanks!
With proc macros rust-analyzer will never invalidate the macro expansion when the .isle files change, not will cargo know that it needs to rebuild if they change. Proc macros don't have any way to declare which files they read.
ah right I forgot about that! Good reason to stick with build scripts, and great to hear rust-analyzer supports it as well!
Last updated: Dec 23 2024 at 12:05 UTC