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



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
└── player

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

snowflake = "*"

The code in is just:

mod player;

While in I wrote this little code:

extern crate snowflake;

use snowflake::ProcessUniqueId;

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 is empty for the moment.

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

src/player/ 3:14 error: unresolved import `snowflake::ProcessUniqueId`. Did you mean `self::snowflake`?
src/player/ 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

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 (idiomatic) or use use self::snowflake::ProcessUniqueId.

Taking suggestions for the new Rust FAQ!

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.


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.