Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic macro support #752

Open
Manishearth opened this issue Dec 20, 2024 · 7 comments
Open

Basic macro support #752

Manishearth opened this issue Dec 20, 2024 · 7 comments
Labels
A-bridge-UX Area: UX improvements for people writing bridge modules A-parsing Improvements to Diplomat's parsing code enhancement New feature or request

Comments

@Manishearth
Copy link
Contributor

For the purposes of cleanly writing code, it would be nice if the AST parser supported using macros. These could expand to types or methods, and would not support nested interpolation.

We'd only support:

  • macros with a single arm
  • the single arm must be a sequence of comma separated matchers, no fancy parsing
  • the macro can be found in item or impl item position, nowhere else (not type position).
  • the macro does not use interpolation matchers

This type of thing is relatively straightforward to parse and interpolate.

These macro definitions would be tagged with diplomat::macro and used in the source code.

The main challenge is that the Diplomat macro would only be able to see macros defined in the same bridge module they are used in. In theory we could apply a #[diplomat::macro_load = src/macros.rs] attribute, and have a global cache of macro_load paths to named Diplomat macros to avoid reparsing each time. It's not pretty, but it would work. We'd have to (at runtime) read CARGO_MANIFEST_DIR.

@Manishearth Manishearth added A-bridge-UX Area: UX improvements for people writing bridge modules A-parsing Improvements to Diplomat's parsing code enhancement New feature or request labels Dec 20, 2024
@Manishearth
Copy link
Contributor Author

I'm not planning on doing this, but it would be cool. It would be pure Diplomat AST code, and would not affect the HIR or backends.

@Manishearth
Copy link
Contributor Author

I found myself wanting something like this when I was redoing ICU4X's constructors over FFI, which follow a pattern. That would be cleaner with a single macro invocation on every formatter type that generates the compiled and buffer ctors.

It would also probably be useful in unicode-org/icu4x#5940 in case we decide to make a ton of formatter types.

@ambiguousname
Copy link
Member

Seconding that this would be cool. I love Rust's macro system and I think it'd be great to bring any small part of that to Diplomat

@Walter-Reactor
Copy link
Contributor

It'd require some rearchitecture, but you could add full macro support by making the bridge macro also spit out a function that returned the HIR representation of the module, which would then be passed to a Generate function in a build.rs file in a separate crate. This is more or less what Interoptopus does:
https://github.com/ralfbiedert/interoptopus/blob/master/examples/real_project_layout/core_library_ffi_build/build.rs

@Manishearth
Copy link
Contributor Author

Yeah, part of the goal here is that cargo build should work without build scripts. I'd rather not go down that route; I'm okay with some boilerplate being needed to cross-link macro files.

@Walter-Reactor
Copy link
Contributor

Walter-Reactor commented Jan 28, 2025

Would adding support for !include, !concat, and !env("OUT_DIR") be in scope? doing codegen in build.rs & including it in a src file via include!(concat!(env!("OUT_DIR"), "/generated.rs")); is relatively common

@Manishearth
Copy link
Contributor Author

There are two things that seem brittle with that:

  • Are proc macros supposed to use env vars? It's not clear to me that they are, this issue seems to indicate that it's not really a supported use case, though it kind of works.
  • The proc_macro2 internal swappable token tree impl may not like parsed tokens from this file. Probably fine if it works.

So, worth a shot, but I'm wary it'll be brittle.

I'd also not use the builtin macros for this, I'd just make a fake include_outdir!() macro.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-bridge-UX Area: UX improvements for people writing bridge modules A-parsing Improvements to Diplomat's parsing code enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants