Is there any tools similar to Clang AST, which can generate codes from a real AST, not a token stream?

In my case I need to generate codes depend on some type informations, for example pick up all types which implement some trait and generate a new struct with these types. But derive macro cannot do this since it takes tokens, which are barely literals, without any type information.

I solve this in C++ by using Clang AST, but now I decide to port my project into Rust totally, this part blocks me a while.

So how do you experts deal with this problem (in this case checking trait implementation in macros), and is there something similar to Clang AST?

You're probably looking for something like syn+quote, if I understand correctly (former is for parsing, latter is for generating).

1 Like

Sorry, not really, this question appears exactly because syn+quote is parsing tokens, no type information can be retrieved.

You may need to run the rustc_driver yourself which essentially is a rustc-as-a-library. This is the way how the rust-analyzer access the type information.

It's a good point to investigate, and do you know whether a proc-macro lib use the same tech? All I know is that a proc-macro lib acts like a compiler plugin, but don't know how it is implemented.

Macros including the proc-macro are expanded during the parsing stage, which happens before the type information is constructed. All you can see within the proc-macro is the token stream.

1 Like

No, I mean is a proc-macro lib a programmer wrote turns into a rustc_driver, which is loaded into the compiler when compiling, or it uses some other features in Rust.

Proc-macros are completely independent from implementation details of rustc like rustc_driver. Unlike those implementation details, proc-macro has a stable api. Proc-macros are also technically not tied to rustc. For example rust-analyzer can load the same compiled proc-macro's. The internal interface used to communicate between the proc-macro and rustc is unstable though. Proc-macros internally work by having the macro expander call a function from the proc-macro and provide a callback. The proc-macro then uses this callback every time it needs to know something about the input tokenstream, or when it wants to construct a part of the tokenstream. The proc-macro is completely oblivious to the internals of rustc.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.