Modules and Visibility

pub(super)

The pub(super) visibility modifier makes an item, struct field, or method visible to the immediate parent module (super) and all of that parent module's descendants, while keeping it hidden from grandparent modules and the rest of the crate.

How pub(super) Scopes Visibility

Module Hierarchy Showing `pub(super)` Reachability:

  crate (root)                         <-- Cannot access `helper()` (grandparent!)
   └── mod subsystem                   <-- Parent (`super`): CAN access `worker::helper()`
        ├── mod worker                 <-- Defining module: defines `pub(super) fn helper()`
        └── mod monitor                <-- Sibling under `subsystem`: CAN access `super::worker::helper()`
Location in Module Tree Can Access pub(super) Item in crate::subsystem::worker?
crate::subsystem::worker (defining module & children) Yes
crate::subsystem (immediate parent module) Yes
crate::subsystem::monitor (sibling module sharing the same parent) Yes
crate (root module / grandparent) No (E0603 / E0624)

Encapsulating Subsystem Internals with pub(super)

When a parent module (mod database) splits its implementation across several child submodules (mod pool and mod query), pub(super) allows those child modules and their parent database module to share low-level helpers without exposing them to the rest of the crate:

mod database {
    mod connection {
        pub struct Conn {
            pub(super) fd: u32,
        }

        // Only `mod database` and its child submodules (`query`) can call `open_raw`:
        pub(super) fn open_raw(fd: u32) -> Conn {
            Conn { fd }
        }
    }

    mod query {
        // Sibling submodule under `database` can access `pub(super)` items in `connection`:
        pub(super) fn run_on_conn(conn: &super::connection::Conn, sql: &str) -> String {
            format!("[fd={}] executed: {sql}", conn.fd)
        }
    }

    // Public facade exposed by `database` to the rest of the crate:
    pub fn execute_query(sql: &str) -> String {
        let conn = connection::open_raw(7);
        query::run_on_conn(&conn, sql)
    }
}

fn main() {
    let result = database::execute_query("SELECT 1;");
    println!("{result}");
}
[fd=7] executed: SELECT 1;

Compile Error When Accessing pub(super) from a Grandparent Module (E0603)

Attempting to call a pub(super) function from outside the immediate parent module's subtree fails at compile time:

// ❌ does not compile
mod outer {
    pub mod inner {
        pub(super) fn secret_step() {}
    }
}

fn main() {
    // `main` is in the crate root (grandparent of `inner`), so `secret_step` is private here:
    outer::inner::secret_step();
}
error[E0603]: function `secret_step` is private
  --> src/main.rs:10:19
   |
10 |     outer::inner::secret_step();
   |                   ^^^^^^^^^^^ private function
   |
note: the function `secret_step` is defined here
  --> src/main.rs:3:9
   |
3  |         pub(super) fn secret_step() {}
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^