Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unresolved import in documentation example

Tags:

rust

rustdoc

I'm having difficulty fixing an error inside my documentation example for my library. I have the file structure like for my crate bignum

.
|-- Cargo.lock
|-- Cargo.toml
|-- examples
|   |-- dat
|   |   `-- euler_13.dat
|   |-- debug.rs
|   `-- euler_13.rs
|-- README.md
|-- src
|   |-- error.rs
|   |-- inits.rs
|   `-- lib.rs

In my examples, my headers will look something like

// euler_13.rs 
extern crate bignum;
use bignum::inits::Zero;

// ...

This compiles and works great, but now when I'm writing an example inside my documentation at lib.rs, I can't seem to import bignum::inits::Zero

//lib.rs
//...

impl BigNum {

    //...


    /// Constructs a ...
    ///
    /// # Examples
    ///
    /// ```
    /// extern crate bignum;
    /// use bignum::inits::Zero;
    ///
    /// let a = bignum::BigNum::new(Zero::zero());
    /// ```
    ///
    pub fn new(base: BigNum) -> BigNum {
        // ...
    }

When I run cargo test, I receive this error

     Running target/debug/lib-fe3dd7a75a504b04

running 3 tests
test crate_from_u32 ... ok
test create_from_string ... ok
test adding_no_carry ... ok

test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured

   Doc-tests bignum

running 1 test
test new_0 ... FAILED

failures:

---- new_0 stdout ----
    <anon>:3:9: 3:15 error: unresolved import `self::bignum::inits::Zero`. Did you mean `self::self::bignum::inits`?
<anon>:3     use self::bignum::inits::Zero;
                 ^~~~~~
error: aborting due to previous error
thread 'new_0' panicked at 'Box<Any>', /home/rustbuild/src/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libsyntax/diagnostic.rs:192



failures:
    new_0

I've seen this question, but this deals with importing modules from the same file which still require toplevel scope. However here i'm still specifying top level scope with bignum::.

So while importing bignum::inits::Zero works for all of my tests and examples, it doesn't work for my docs. Why is that? I've tried appending self:: in front and receive the same error. If i change the doc examples to

extern crate bignum;

let a = bignum::BigNum::new(bignum::inits::Zero::zero());

it compiles fine however. How can I correctly import my modules?

like image 544
Syntactic Fructose Avatar asked Jul 26 '15 14:07

Syntactic Fructose


2 Answers

I think the problem stems from this useful feature of the doc tests:

rustdoc will automatically add a main() wrapper around your code, and in the right place.

If you apply the rules in the link, you end up compiling code like this:

fn main() {
   extern crate bignum;
   use bignum::inits::Zero;

   let a = bignum::BigNum::new(Zero::zero());
}

You would then indeed need to refer to it as self::bignum, as the first error message suggests. Unfortunately, that won't currently work because of Rust issue 23314.

like image 114
Shepmaster Avatar answered Nov 15 '22 02:11

Shepmaster


So the reason this error is generated boils down to extern crate bignum implicitly being used by the documentation examples, meaning I shouldn't need to explicitly tell the example I'll be using bignum.

This makes sense because at the documentation level, examples show how the functionality of a specific part of your crate should work, so you'll be using bignum regardless. cargo recognizes this and imports bignum for you. What the example should look like is:

//lib.rs
//...

impl BigNum {

    //...


    /// Constructs a ...
    ///
    /// # Examples
    ///
    /// ```
    /// use bignum::inits::Zero;
    ///
    /// let a = bignum::BigNum::new(Zero::zero());
    /// ```
    ///
    pub fn new(base: BigNum) -> BigNum {
        // ...
    }
}
like image 34
Syntactic Fructose Avatar answered Nov 15 '22 01:11

Syntactic Fructose