"找不到宏"宏的自己的doc测试中出错

时间:2015-07-27 02:41:19

标签: rust

我正在尝试将文档测试添加到我导出的Rust宏中。像这样:

/// Usage:
///
/// ```
/// let x = addone!(100);
/// ```
#[macro_export]
macro_rules! addone {
    ($x:expr) => ($x + 1)
}

如果我对此运行cargo test,我会

failures:

---- src/lib.rs - addone (line 3) stdout ----
    error: cannot find macro `addone!` in this scope
 --> src/lib.rs:2:9
  |
2 | let x = addone!(100);
  |         ^^^^^^

我无法想到在文档测试中添加macro_use的合法方式,所以没有运气。

macros in Rust's standard library遵循与上述代码相同的格式,因此我希望它能够正常运行。

2 个答案:

答案 0 :(得分:14)

如果代码块在代码中找不到这些元素,则文档测试会自动将代码块包装在extern crate foo; fn main() { … }中,但要获取导出的宏,您需要#[macro_use]上的extern crate foo;属性

因此,你应该这样写:

/// Usage:
///
/// ```
/// # #[macro_use] extern crate foo; fn main() {
/// let x = addone!(100);
/// # }
/// ```
#[macro_export]
macro_rules! addone {
    ($x:expr) => ($x + 1)
}

(以为前缀的行隐藏在输出中,但是在为doc测试编译的代码中包含 sans 标记。)

The Rust Programming Language, first edition中介绍了这一点。

至于std,所有包含#[macro_use] extern crate std; crate属性的包中都隐含#![no_std],因此其宏会立即生效。

答案 1 :(得分:1)

Rust编程语言显示how to write doc tests for macros

  

您会注意到三件事:我们需要添加自己的extern crate行,以便我们可以添加#[macro_use]属性。其次,我们还需要添加自己的main()。最后,明智地使用#来评论这两件事,因此它们不会出现在输出中。

我猜了一下,但Rust标准库不需要这个的原因是因为标准库中的所有宏都是自动导入的,所以没有理由明确use它们。