How do you use parent module imports in Rust?

I’m going to answer this question too, for anyone else who finds this and is (like me) totally confused by the difficult-to-comprehend answers.

It boils down to two things I feel are poorly explained in the tutorial:

  • The mod blah; syntax imports a file for the compiler. You must use this on all the files you want to compile.

  • As well as shared libraries, any local module that is defined can be imported into the current scope using use blah::blah;.

A typical example would be:

src/main.rs
src/one/one.rs
src/two/two.rs

In this case, you can have code in one.rs from two.rs by using use:

use two::two;  // <-- Imports two::two into the local scope as 'two::'

pub fn bar() {
    println!("one");
    two::foo();
}

However, main.rs will have to be something like:

use one::one::bar;        // <-- Use one::one::bar 
mod one { pub mod one; }  // <-- Awkwardly import one.rs as a file to compile.

// Notice how we have to awkwardly import two/two.rs even though we don't
// actually use it in this file; if we don't, then the compiler will never
// load it, and one/one.rs will be unable to resolve two::two.
mod two { pub mod two; }  

fn main() {
    bar();
}

Notice that you can use the blah/mod.rs file to somewhat alleviate the awkwardness, by placing a file like one/mod.rs, because mod x; attempts x.rs and x/mod.rs as loads.

// one/mod.rs
pub mod one.rs

You can reduce the awkward file imports at the top of main.rs to:

use one::one::bar;       
mod one; // <-- Loads one/mod.rs, which loads one/one.rs.
mod two; // <-- This is still awkward since we don't two, but unavoidable.    

fn main() {
    bar();
}

There’s an example project doing this on Github.

It’s worth noting that modules are independent of the files the code blocks are contained in; although it would appear the only way to load a file blah.rs is to create a module called blah, you can use the #[path] to get around this, if you need to for some reason. Unfortunately, it doesn’t appear to support wildcards, aggregating functions from multiple files into a top-level module is rather tedious.

Leave a Comment