Span pointing to its own construction site like Location::caller
- Dominant language
- Rust
- Stars
- 934
- Forks
- 135
- PR merge metrics
- No merged PRs in 30d
Description
I couldn't easily figure by myself reading the code and documentation of `proc-macro` and `proc-macro2`, so asking here. Is it possible to generate a `Span` that points to its own span? Or maybe asked differently, is it possible to create a `Span` from (or similarly to) a `core::panic::Location` (or 2 to make it an actual span, but a point in code is enough for me)?
Here's the motivation (which I would understand if it's not something `proc-macro` is trying to address):
- I would like to use `proc-macro` to generate code from some data-structure describing the code to be generated (see below for why this data-structure cannot be a token stream).
- This data-structure would be built within the `proc-macro` crate itself (or eventually from a dependency crate).
- When building this data-structure, I would like to "capture" the `Span` of constructor calls.
- I would then use `quote_spanned!()` to generate the `proc-macro` output based on those `Span`s.
- (I hope `rust-analyzer` would then be able to point me back to the correct place in the `proc-macro` crate when looking for definitions generated by the proc-macro.)
Here's a sketch of a concret example:
```rust
enum Input { ... } // data-structure to generate code from
#[proc_macro]
pub fn generate(_: TokenStream) -> TokenStream {
// We don't need the proc-macro input. We use the `Input` data-structure.
let input = Input::generate(); // The input is actually constant, but built dynamically.
input.into_token_stream().into()
}
impl Input {
fn generate() -> Input {
...
let span = Span::caller(); // This behaves like Location::caller();
let sub_input = SubInput::Foo { span, ... };
...
let span = Span::caller(); // All those calls could be split in multiple modules and possibly crates.
Input::Bar { span, sub_input, ... }
}
}
impl ToTokens for Input {
fn to_tokens(&self, tokens: &mut TokenStream2) {
...
tokens.extend(quote_spanned!(sub_input.span => ...));
...
}
}
```
The reason to not use the input token stream is that it doesn't support going through modules recursively. I would like my data-structure (or equivalently the `proc-macro` input) to be hierarchically structured through multiple files like the module hierarchy in a crate does. In other words, the following alternatives would also work for me:
- It is possible within a proc-macro to read the content of a file (relative to the initial macro invocation) as a token stream.
- It is possible for a proc-macro to take a full crate as input, where modules are flattened as if it was a single file. (But this assumes the proc-macro input is valid Rust, which adds a usage constraint.)
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.