39

There's a lot of Rust documentation about using modules, but I haven't found an example of a Cargo binary that has multiple modules, with one module using another. My example has three files inside the src folder. Modules a and b are at the same level. One is not a submodule of another.

main.rs:

mod a;

fn main() {
    println!("Hello, world!");
    a::a();
}

a.rs:

pub fn a() {
    println!("A");
    b::b();
}

and b.rs:

pub fn b() {
    println!("B");
}

I've tried variations of use b and mod b inside a.rs, but I cannot get this code to compile. If I try to use use b, for example, I get the following error:

 --> src/a.rs:1:5
  |
1 | use b;
  |     ^ no `b` in the root. Did you mean to use `a`?

What's the right way to have Rust recognize that I want to use module b from module a inside a cargo app?

  • 1
    Interesting, I thought I was the only one who did not understand that part in the docs. However, it was easy to know by experimenting with it. – VP. Jan 03 '18 at 14:26

3 Answers3

48

You'll have to include b.rs somewhere, typically with mod b;. If b is a child of a (instead of being a sibling of a), there are two ways to do this:

  • Recommended: rename a.rs into a/mod.rs and b.rs into a/b.rs. Then you can mod b; in a/mod.rs.
  • Instead, you can just #[path = "b.rs"] mod b; in a.rs without renaming sources.

If b is intended to be a sibling of a (instead of being a child of a), you can just mod b; in main.rs and then use crate::b; in a.rs.

trent
  • 25,033
  • 7
  • 51
  • 90
Masaki Hara
  • 3,295
  • 21
  • 21
  • 17
    Thanks. That seems counterintuitive. I need to `mod b` in `main.rs` in order to `use b` in `a.rs`. –  Jan 03 '18 at 15:33
  • 2
    The idea is that `mod` is for building the module tree and `use` is for short-circuiting it. The absolute path `::b::b();` works without `use b;`. (Note that the syntax for absolute paths will change in future versions of Rust, in favor of [RFC 2126](https://github.com/rust-lang/rfcs/blob/master/text/2126-path-clarity.md).) – Masaki Hara Jan 04 '18 at 01:33
  • @user8360684 Agreed – TomLisankie Aug 21 '21 at 01:34
25

The method from the accepted answer doesn't work for me in Rust 1.33. Instead, I use the sibling module like this:

use crate::b;
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Dovchik
  • 410
  • 5
  • 9
1

In the latest Rust 1.63, we can use super keyword to refer siblings

// main.rs
mod a;
mod b;

fn main() {
}

// a.rs
pub fn a() {
    println!("A");
    super::b::b();
}

// b.rs
pub fn b() {
    println!("B");
}
edvard chen
  • 2,320
  • 1
  • 12
  • 10