Modules and Visibility
Nested Modules
A nested module is a mod declared inside another mod, forming a multi-level hierarchy in the crate's module tree—either inline within a single source file or across nested subdirectories on disk.
Inline Nested Modules vs. File-Backed Nested Modules
Both inline nested mod blocks and directory-backed mod files produce the exact same logical module tree and obey the exact same visibility rules:
Inline Nested Modules (Single File): File-Backed Nested Modules (`src/`):
mod cloud { src/
pub mod storage { ├── main.rs (`mod cloud;`)
pub mod s3 { ├── cloud.rs (`pub mod storage;`)
pub fn upload() {} └── cloud/
} ├── storage.rs (`pub mod s3;`)
} └── storage/
} └── s3.rs (`pub fn upload() {}`)
Visibility Rules Across Nested Modules
- Top-down reachability requires every intermediate module to be visible: For code outside
cloudto callcloud::storage::s3::upload(),storage,s3, anduploadmust all be markedpub(or re-exported viapub use). - Bottom-up access to private ancestors is automatic: Code inside
cloud::storage::s3can access private items incloud::storage,cloud, and thecrateroot without anypubannotations on those ancestor items.
mod cloud {
// Private constant in `cloud`: visible to all nested descendants (`storage` and `s3`)
const REGION: &str = "ap-southeast-1";
pub mod storage {
const BUCKET_PREFIX: &str = "prod";
pub mod s3 {
pub fn object_uri(key: &str) -> String {
// Access private constants from both parent (`storage`) and grandparent (`cloud`):
let region = super::super::REGION;
let prefix = super::BUCKET_PREFIX;
format!("s3://{prefix}-{region}/{key}")
}
}
}
}
fn main() {
let uri = cloud::storage::s3::object_uri("snapshots/2026-10-22.tar.zst");
println!("Target URI: {uri}");
}
Target URI: s3://prod-ap-southeast-1/snapshots/2026-10-22.tar.zst
Error When an Intermediate Nested Module Is Private (E0603)
If a nested function s3::upload() is marked pub, but its parent module mod s3 is left private, callers outside storage cannot traverse through s3:
// ❌ does not compile
mod cloud {
pub mod storage {
mod s3 {
pub fn upload() {}
}
}
}
fn main() {
cloud::storage::s3::upload();
}
error[E0603]: module `s3` is private
--> src/main.rs:10:21
|
10 | cloud::storage::s3::upload();
| ^^ ------ function `upload` is not publicly re-exported
| |
| private module
|
note: the module `s3` is defined here
--> src/main.rs:3:9
|
3 | mod s3 {
| ^^^^^^
To allow callers to invoke upload() without making mod s3 public, either mark pub mod s3 or add pub use self::s3::upload; inside pub mod storage.