Type inferencing in a procedural macro

Hi,

I am working on a procedural macro. It takes a TokenStream, parses it into a syn AST, converts it into another syn AST, and finally parses it back to a TokenStream. I was wondering whether there is a way to infer types of variables at this level. I haven't found anything in the syn library yet, but I guess that makes sense because syn is about syntax.

Essentially, I want to track all the integers and bools in my syn AST. I'm currently thinking of writing some recursive thing that would probably be based on some type inferencing algorithm, but it feels like I''ll be reinventing the wheel.

If there is some library out there, it would be great if you could let me know. Any advice on going about the type inference mechanism would also be nice.

Thanks!

I don't think that this is possible in general (or even in specific) unless the variables are marked themselves.

Given that this generally depending on the return values of functions, you would basically have to complete some amount of type checking of the whole program (which I assume is not the input to your macro).

This is better suited for users.rust-lang.org, though what @Nokel81 said is generally correct.

I personally don't think that type-driven macros are a good idea for Rust at this point. I know they are very powerful in D. What you often can do instead is structure your operations so the type system will choose the correct action for you, as I did in mutagen (see blog post, and note that while mutagen uses the still-unstable specialization, autoref specialization works today).

2 Likes

Given how syntactic macros work (i.e. their expander code is run before things like typeck and borrowck are run) I think that the only way to achieve this is to introduce a library that provides type checking capabilities for Rust code. No such library currently exists AFAIK; the ideal case would be to yank the code directly out of rustc and into such a library ¹. But I don't see that happening anytime soon either, as the language team has quite a lot on their plate already (perhaps too much).

On top of that, let's assume such a library existed. Then there's the conceptual issue that now typechecking and macro expansion are being interleaved. I'm not so sure that that would be a good idea, for reasons of comprehensibility, performance and maintainability. This is because sure the easy cases can be done quickly. But what if someone then writes a macro that makes heavy use of such interleaving? Would the result still be maintainable, performant and comprehensible?

¹If it isn't an official part of rustc, it'll likely always lag behind a while when updates to the type checking subsystem are made, which leads to situations where a part of the ecosystem actively has to avoid using the latest stable toolchain. Crates that have at least 1 such dependency, but also a dependency requiring the latest version (e.g. because it uses a language feature that was just introduced) would be in real trouble. So I think it's best to nip that in the bud and prevent such situations from occurring altogether.

3 Likes

Thank you for all the comments! These have been quite helpful and informative. Also, I actually found a way to pretty much ignore type inferencing for my purposes (for now).