I am generating a Rust module via a procedural macro attribute. When using this generated code, I get no auto-complete suggestions or hover info.
However, some procedurally-generated code does appear in autocomplete suggestions, e.g. the example code in json-typegen:
use json_typegen::json_typegen;
// `Point` and fields present in auto-complete
json_typegen!("pub Point", r#"{ "x": 1, "y": 2 }"#);
The two major differences I see here are that this is just a type, not a module; and it is using a function-like proc macro. Don't know if these are relevant though.
Are there any known guidelines I could follow with my procedural macro to make RA more likely to function with it?
Thanks! So if I converted my codegen to a function-like macro, is it likely that autocomplete etc. would work? Are there any other caveats with the current system?
They may work, but I won't necessary say "likely" Our code-generation support (both for proc-macro and for include) is pretty thin at the moment. I'd advise to maybe try some minimal proof of concepts just to see if rust-analyzer can understand those.
Thanks for the advice. If it doesn't work, I'm probably going to look at generating to a file at a known location (xtask?), since support for #[path = "..."] mod x; seems to work perfectly.
Yeah, you might want to check the codegen.rs module from rust-analyzer's own code, we do use boring codegen instead of proc macros.
More philosophically, I think that codegeneration, if feasible, should be preferred to proc-macros. If there's actual code on the hard-drive, than it becomes easy to do things like:
read what's actually geneated
step with debugger through the generated code
use goto definition in an IDE to look at the generated code
To be clear, it totally is a bug that rust-analyze doesn't support proc macros fully, and, while I am willing to argue for codegen over proc-macros as a user of the language, I just need to fix rust-analyzer as the tool's contributor
This is true, although I think derive/proc macros have benefits too:
No need to make a "generated" partitioning folder/gitignore rules
It means anything a user can physically edit is a legitimate code change (instead of having to instruct users that some files should be treated as "read only")
Code generation might be unsuitable to read directly, but the directive for the proc macro itself is meaningful (e.g. derive(Serialize) and serde attributes).
I can imagine the best-of-both would be the ability to preview generated code, without it existing in a file. I'm not sure if the LSP supports something like this, but it seems similar to the ability to view generated "header" files for dependencies in C# projects.
In fact, this would be better than something like cargo expand (or full code generation to file), if it meant you could view only the code generated from a proc macro directive, without any nested directives being expanded also. E.g. it might be more useful to see which derives have been added to a generated type, than to see the code for those derives in-line.