rust modules resolution from main.rs

Viewed 184

I have a question about rust modules resolution. It seems to be that inside crate modules I can reference the other modules using crate name or crate/super/self keywords. but in main.rs I can only use modules with crate name?

Am I doing something stupid here?

My project:

$ tree
.
├── Cargo.toml
└── src
    ├── add2.rs
    ├── add.rs
    ├── lib.rs
    └── main.rs

Cargo.toml content:

[package]
name = "example"
....

main.rs content:

use example::add::{add_one};
fn main() {
    println!("{}", add_one(1));
}

lib.rs content:

pub mod add;

add.rs content:

pub fn add_one(x: i32) -> i32 {
    x + 1
}

add2.rs content:

use crate::add::{add_one};

pub fn add_two(x: i32) -> i32 {
    add_one(add_one(x))
}
2 Answers

Am I doing something stupid here?

No, it`s just that Cargo adds one more layer of complexity called the "package", for better or worse, which makes it more confusing.

In short, your Cargo package contains two Rust crates: the binary one and the library one. When you are in main.rs, the example library crate is an external dependency like any other... which means you aren`t in the same crate!

Crate roots such as main.rs, lib.rs, bin/other_root.rs, etc. are treated differently by the module system. When they refer to module files they are referring to files in the root of the src/ directory only. In the normal case mod refers to files in the root of a local sub-directory with the same name as the containing file, mirroring the unique container constraint of the inline module layout as well as the file system hierarchy (barring linked files, of course). In essence, crate roots treat src/ as their local sub-directory as far as mod is concerned.

I gave perhaps a more wordy explanation here

Related