Error importing a module, but no problem using its absolute path


#1

Hi,

I am having some trouble with crate/modules doing a little test with an external crate (snowflake).
This is the tree of my little project:

├── Cargo.lock
├── Cargo.toml
└── src
├── lib.rs
└── player
    ├── mod.rs
    └── player_test.rs

And in the Cargo.toml I have inserted this row:

[dependencies]
snowflake = "*"

The code in lib.rs is just:

mod player;

While in mod.rs I wrote this little code:

extern crate snowflake;

use snowflake::ProcessUniqueId;

#[cfg(test)]
mod player_test;

/// Represent a player that can join a game.
struct Player {
    /// Player ID, it must be unique for each player.
    pub id: ProcessUniqueId,
}

impl Player {
    fn new() -> Player {
        let new_id = ProcessUniqueId::new();
        Player{ id: new_id }
    }
}

And player_test.rs is empty for the moment.

So, if I try to compile with cargo build I get this error:

src/player/mod.rs:3:5: 3:14 error: unresolved import `snowflake::ProcessUniqueId`. Did you mean `self::snowflake`?
src/player/mod.rs:3 use snowflake::ProcessUniqueId;
                        ^~~~~~~~~

Furthermore there is another strange thing: if I change my code removing the use clause and use the absolute path for the snowflake module I don’t get any errors.
I cannot understand the reason.

Thank you.


Static field in struct and ID generation
#2

Paths in use statements are relative to the crate root so you need self:: to make it relative to the current module. However, paths everywhere else are relative to the current module which is why using snowflake::ProcessUniqueId directly works.

The solution is to either put extern crate snowflake; in lib.rs (idiomatic) or use use self::snowflake::ProcessUniqueId.


Taking suggestions for the new Rust FAQ!
#3

Thank you for the reply.

Sorry, if I am asking again, but I want to be sure that I got it right.
It means that when I write “extern crate xyz” this imports xyz in the current module. While the use statement looks for modules imported in the containing (maybe root is a better word) crate.
So in my case it cannot find snowflake since it has been imported in game::player and use is trying to find it in game.
While when I refers to a module in other place of the code (not in the use statement) their paths are relative to the current module.
Is it right?

Sorry, I am learning Rust by book, examples and also by forum :wink: (so your support is very precious)

Thank you.


#4

Yes. Basically, paths in use statements are absolute (relative to the root) and paths everywhere else are relative (to the current module). a::b::c is a path (e.g. std::collections::HashMap or snowflake::ProcessUniqueId.