Rust Modules Names in code vs names in `use`


Example

The double-colon syntax of names in the use statement looks similar to names used elsewhere in the code, but meaning of these paths is different.

Names in the use statement by default are interpreted as absolute, starting at the crate root. Names elsewhere in the code are relative to the current module.

The statement:

use std::fs::File;

has the same meaning in the main file of the crate as well as in modules. On the other hand, a function name such as std::fs::File::open() will refer to Rust's standard library only in the main file of the crate, because names in the code are interpreted relative to the current module.

fn main() {
    std::fs::File::open("example"); // OK
}

mod my_module {
   fn my_fn() {
       // Error! It means my_module::std::fs::File::open()
       std::fs::File::open("example"); 

       // OK. `::` prefix makes it absolute 
       ::std::fs::File::open("example"); 

       // OK. `super::` reaches out to the parent module, where `std` is present
       super::std::fs::File::open("example"); 
   } 
}

To make std::… names behave everywhere the same as in the root of the crate you could add:

use std;

Conversely, you can make use paths relative by prefixing them with self or super keywords:

 use self::my_module::my_fn;