rust - 在给定父模块上下文中的路径的子模块上下文中生成路径

标签 rust rust-proc-macros

我正在创建一个 attribute macro可以通过其属性中的某种类型(路径)调用:

#[my_macro(path::to::SomeType)]

这个宏生成一个模块,其中指定的类型将被使用:

mod generated {
    use path::to::SomeType;
}

但是,从生成的模块中,提供的路径可能不再正确:

  • 如果路径以 :: 为前缀,它仍然是正确的——我可以在 proc 宏中确定这一点;
  • 否则,如果路径以前奏中的标识符开始(例如外部包装箱的标识符),它仍然是正确的——我看不出有任何方法可以在 proc 宏中确定这一点;
  • 否则它现在必须以 super:: 为前缀才能成功解析。

当然,我可以要求宏的用户在生成的模块中提供一个正确的路径,但这不太符合人体工程学。

相反,我目前正在父模块中生成一个类型别名:

type __generated_SomeType = path::to::SomeType;
mod generated {
    use super::__generated_SomeType as SomeType;
}

但这不仅有点笨拙,而且还会污染父命名空间。

有没有更好的办法?

最佳答案

我认为没有令人满意的解决方案。但还有一种替代方法,可以改进您当前的方法。

另一种方法是使用 const 项:

const _: () = {
    // ... your generated code here
};

它仍然会导致与父作用域中的项目发生名称冲突,但至少生成的项目在 const 之外是不可见的。这是大多数宏作者所做的。

如果你不想这样做,你可以使用你当前的方法,但是你应该添加 #[doc(hidden)]__generated_SomeType 类型,因此它不会出现在文档中。此外,您应该使用导入而不是类型别名来支持泛型类型,正如@ChayimFriedman 所建议的那样:

#[doc(hidden)]
use path::to::SomeType as __generated_SomeType;

我正要建议通过将模块放入 const 项目中来将这些方法结合起来,但它不起作用:

const _: () = {
    use path::to::SomeType as __generated_SomeType;

    mod generated {
        // doesn't work :(
        use super::__generated_SomeType as SomeType;
    }
};

Rust 提示 __generated_SomeType 在父模块中不存在。

关于rust - 在给定父模块上下文中的路径的子模块上下文中生成路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71849696/

相关文章:

rust - 如何在类型上而不是在类型内部使用自定义命名空间派生宏属性?

rust - 如果 Option 中的 .unwrap() 的输出取决于实例本身,它如何成为 const 函数?

rust - 如何为私有(private)元素生成文档

rust - 将枚举变体用作函数的这种奇怪语法是什么?

c++ - 编译为 wasm 的 C++ 和 Rust 程序能否以某种方式互操作?

types - 无法取消引用类型 `usize`

rust - 如何使用亲爱的解析带有嵌套参数的属性?

rust - 如何在程序宏生成的代码中创建卫生标识符?