18

I have a small project which built with no issues when it was all in one big .rs file. I wanted to make it easier to work with, so I broke it up into modules, and the project is now structured like this:

├── GameState
│   ├── ballstate.rs
│   ├── collidable.rs
│   ├── gamestate.rs
│   ├── mod.rs
│   └── playerstate.rs
├── lib.rs
└── main.rs

In ballstate.rs, I need to use the rand crate. Here's an abbreviated version of the file:

extern crate rand;

pub struct BallState {
    dir: Point,         
    frame: BoundingBox  
}                     

impl BallState {
    fn update_dir(&mut self) {
        use rand::*;                                                                                                                                                                    
        let mut rng = rand::thread_rng();                                                                      
        self.dir.x = if rng.gen() { Direction::Forwards.as_float() } else { Direction::Backwards.as_float()  };
        self.dir.y = if rng.gen()  { Direction::Forwards.as_float() } else { Direction::Backwards.as_float() };
    }                                                                                                        
}

However, when I run cargo build from the top level directory, I get the following error:

GameState/ballstate.rs:42:9: 42:13 error: unresolved import rand::*. Maybe a missing extern crate rand?

When I just had the extern crate declaration in my main.rs file, this worked. What's changed now that it's in a separate module?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Ben Pious
  • 4,765
  • 2
  • 22
  • 34

2 Answers2

20

To quote from the Crates and Modules chapter of the Rust book:

[...] use declarations are absolute paths, starting from your crate root. self makes that path relative to your current place in the hierarchy instead.

The compiler is correct; there is no such thing as rand, because you've put it inside a module, so the correct path to it would be GameState::ballstate::rand, or self::rand from within the GameState::ballstate module.

You need to either move extern crate rand; to the root module or use self::rand within the GameState::ballstate module.

DK.
  • 55,277
  • 5
  • 189
  • 162
  • This is the answer I arrived at a few hours ago; thanks for posting (and for pointing out where in that book/tutorial this was stated, I actually read it before posting the question and didn't realize that it had the solution the whole time). I didn't mean to imply that the compiler was wrong, just that I didn't understand exactly what had changed from the one file scenario to the many. – Ben Pious Nov 27 '15 at 04:37
2

You need to put the extern crate rand; line in you main.rs and/or lib.rs file. No need to put it in the other files.

Perhaps it is related to this bug.

antoyo
  • 11,097
  • 7
  • 51
  • 82