有没有办法在编译时获取程序宏附加的文件和模块路径?

tve*_*eeg 6 rust rust-proc-macros

我正在寻找程序宏上下文中的file!()&等价物module_path!()

例如,以下不起作用:

file.rs

#[some_attribute]
const A: bool = true;
Run Code Online (Sandbox Code Playgroud)

macro.rs

#[proc_macro_attribute]
pub fn some_attribute(attr: TokenStream, input: TokenStream) -> TokenStream {
    println!("{}", file!());

    input
}
Run Code Online (Sandbox Code Playgroud)

这打印macro.rs是有道理的,但我想要的是file.rs. 有没有办法实现这一目标?是否也有类似的方法module_path!()

这样做的一个要求是必须在编译时发生。

我正在尝试在OUT_DIR包含常量值的文件中创建一个文件,其中该属性与模块和它们所在的文件一起添加。

小智 11

我遇到了同样的问题,发现 Rust 向 Rust 宏添加了一个新的实验性 API ( #54725 ),它完全可以满足您的需求:

#![feature(proc_macro_span)]

#[proc_macro]
pub(crate) fn do_something(item: TokenStream) -> TokenStream {
    let span = Span::call_site();
    let source = span.source_file();
    format!("println!(r#\"Path: {}\"#)", source.path().to_str().unwrap())
        .parse()
        .unwrap()
}
Run Code Online (Sandbox Code Playgroud)
use my_macro_crate::*;

fn main() {
    println!("Hello, world!");
    do_something!();
}
Run Code Online (Sandbox Code Playgroud)

将输出:

Hello, world!
Path: src\main.rs
Run Code Online (Sandbox Code Playgroud)

重要的

除了该 API 是实验性的之外,该路径可能不是真正的操作系统路径。Span如果是由宏生成的,则可能出现这种情况。请访问此处的文档。