Modules and Visibility

crate, self, and super

Rust provides three path-anchor keywords—crate, self, and super—to navigate the module tree unambiguously without colliding with external crate names or local identifiers.

Meaning of Each Path Keyword

Keyword Meaning in Module Paths Filesystem Equivalent
crate The root module of the current crate (src/lib.rs or src/main.rs) /
self The current module containing the path .
super The immediate parent module of the current module (can be chained: super::super::...) ..
Navigating with `crate`, `self`, and `super` from `crate::net::http`:

  crate                    <-- `crate::` OR `super::super::`
   └── mod net             <-- `crate::net::` OR `super::`
        └── mod http       <-- `crate::net::http::` OR `self::`
             └── mod v2    <-- `self::v2::` OR `v2::`

Using crate, self, and super Together

fn root_version() -> &'static str {
    "2024.1"
}

mod engine {
    pub fn engine_name() -> &'static str {
        "Vortex"
    }

    pub mod renderer {
        fn local_backend() -> &'static str {
            "Metal"
        }

        pub mod shader {
            pub fn banner() -> String {
                // 1. `crate::` reaches the crate root (`root_version`)
                let ver = crate::root_version();

                // 2. `super::super::` climbs two levels to `mod engine` (`engine_name`)
                let eng = super::super::engine_name();

                // 3. `super::` climbs one level to `mod renderer` (can access private `local_backend`)
                let api = super::local_backend();

                // 4. `self::` refers to the current module `mod shader` (`shader_stage`)
                let stage = self::shader_stage();

                format!("{eng} v{ver} [{api} / {stage}]")
            }

            fn shader_stage() -> &'static str {
                "fragment"
            }
        }
    }
}

fn main() {
    println!("{}", engine::renderer::shader::banner());
}
Vortex v2024.1 [Metal / fragment]

Using self Inside Grouped use Declarations

Inside a braced use list, self imports the module itself alongside selected items inside that module:

mod math {
    pub mod trig {
        pub const PI: f64 = std::f64::consts::PI;
        pub fn deg_to_rad(deg: f64) -> f64 {
            deg * (PI / 180.0)
        }
    }
}

// Brings both `trig` (the module) AND `PI` (the constant inside `trig`) into scope:
use crate::math::trig::{self, PI};

fn main() {
    println!("PI = {PI:.4}");
    println!("90° in radians = {:.4}", trig::deg_to_rad(90.0));
}
PI = 3.1416
90° in radians = 1.5708

Error: Using super at the Crate Root (E0433)

Because the crate root (src/main.rs or src/lib.rs) has no parent module, writing super:: at the top level of the crate root fails at compile time:

// ❌ does not compile
use super::something;

fn main() {}
error[E0433]: failed to resolve: there are too many leading `super` keywords
 --> src/main.rs:1:5
  |
1 | use super::something;
  |     ^^^^^ there are too many leading `super` keywords