How to use a macro in the doc test?


#1

I have defined a macro bar! in my crate mylib (it is in a private module named macros):

#[macro_use]
mod macros {
    /// # Exmaples
    ///
    /// ```rust
    /// use mylib::*;
    ///
    /// println!("{:?}", bar!(1));
    /// ```
    #[macro_export]
    macro_rules! bar {
         ($val:expr) => {
              vec![$val]
         }
    }
}

However, when I run cargo test, it says that error: macro undefined: 'bar!'. What is the problem?


#2

That’s not how you import macros. You should read the section of the book on macro import/export. And yes, you need to import them even for doc tests.


#3

If I import the macro in the doc test as

#[macro_use]
extern crate mylib;

use mylib::*;

There is also an error: anextern crateloading macros must be at the crate root.


#4

You need to introduce an explicit fn main() { ... } around your code (and put extern crate outside that function). Rustdoc automatically puts it when you don’t have written it yourself, but this convenience cannot coexist with extern crate.


#5

Ah; tests are automatically wrapped in fn main() { … } and, as the error says, you can’t load a macro crate anywhere except from the root module.

To get around that, you just have to write an explicit fn main() somewhere in the doc test. Here’s an example of a macro doc test (note that lines that begin with #␣ are hidden from the rendered HTML).