0

I have a build script where I have access to a lot of information about another crate via cargo_metadata.

Now I'm looking for the way to find all invocations of a specific proc-macro inside the another crate.

Theoretically, I can parse another crate's sources by myself but I prefer to avoid it in any way possible for the well known reasons :-)

Ideally, I'm looking for the crate which is used by the compiler already. Or at least the crate which somehow use compiler's output to collect that kind of information.

But any solution will be helpful!

There is how ideal solution may looks like from my code prospective:

use proc_macro::TokenStream;

use some_cool_crate::macros_lookup;
use some_cool_crate::Macros;

let path_to_another_crates_cargo_toml = "/path/to/another_crate/Cargo.toml";
let macros = Macros {
    name: "my_macro",
    crate: "macro_original_crate",
};

// The thing I'm looking for:
macros_lookup(
    path_to_another_crates_cargo_toml, 
    &macros, 
    |attr: TokenStream, input: TokenStream,| {
        // there I'll do some interesting stuff
    },
);

P.S. Currently I obtain the information from custom section of Cargo.toml's [package.metadata] but it requires me to keep Cargo.toml in sync with the sources.

P.P.S. The reason I'm doing all that "cool" stuff is broken Re-exporting C symbols for cdylib

MaxV
  • 2,601
  • 3
  • 18
  • 25
  • 1
    Actually, this is not at all straightforward—and essentially requires much of the compiler front-end: (1) just because the target macro is exported as `my_macro` by a package named `macro_original_crate `, doesn't mean it's invoked as `::macro_original_crate::my_macro` in the source files (the dependency could have been renamed in the `Cargo.toml` and either or both of crate and macro could be bound to alternative names in `use` declarations); (2) other macros might expand to code that invokes your macro of interest. Accordingly both name resolution and macro expansion need to be performed. – eggyal Oct 02 '20 at 01:02
  • @eggyal, thanks for your help. Yes, it requires much of the compiler front-end :-( May be we can ask compiler to provide that kind of information to the external world somehow... – MaxV Oct 02 '20 at 01:08
  • And of course plenty of other build-time variables (such as feature flags, compilation target etc) affect what code is actually compiled—so those would need to be considered too, possibly along with executing any build scripts... and that's after you have already addressed the (simple??) question of merely locating the correct source files...! You may well be able to use some of the crates that comprise rustc to perform these tasks but I don't think it will be a small undertaking. – eggyal Oct 02 '20 at 01:08
  • @eggyal, I can control the environment of the compiler: as the next step my build script asks `cargo` to compile all the other crates. It's a little bit crazy, I know. – MaxV Oct 02 '20 at 01:11
  • It looks like [rust-analyzer](https://github.com/rust-analyzer/rust-analyzer)'s crates may be helpful. – MaxV Oct 08 '20 at 06:31

0 Answers0