Modules and Visibility
pub(in path)
The pub(in path) visibility modifier restricts an item, field, or method's visibility to a specific ancestor module identified by path (and all of that ancestor's descendant submodules).
Rules for the path in pub(in path)
- Must be an ancestor of the current module: You can only grant visibility to a module that encloses the current module (
crate::...,super::..., orself). You cannot grant visibility exclusively to an unrelated sibling subtree without including the lowest common ancestor. - In Rust 2018 and 2024 editions,
pathmust start withcrate::,super::, orself(for example,pub(in crate::network)orpub(in super::super)). pub(crate),pub(super), andpub(self)are shorthands:pub(crate)is shorthand forpub(in crate).pub(super)is shorthand forpub(in super).pub(self)is shorthand forpub(in self)(identical to default private visibility).
Scoping Visibility to an Ancestor Subtree (`pub(in crate::http)`):
crate
├── mod telemetry <-- Outside `crate::http`: CANNOT access `parse_raw_frame`
└── mod http <-- Target ancestor `crate::http`: CAN access
├── mod h2
│ └── mod frame <-- Defines `pub(in crate::http) fn parse_raw_frame()`
└── mod client <-- Inside `crate::http`: CAN access `parse_raw_frame()`
Sharing Deeply Nested Items Across a Subsystem (pub(in crate::...))
When an item is defined two or more levels deep inside a subsystem (crate::http::h2::frame), pub(super) only reaches crate::http::h2, whereas pub(crate) exposes it to the entire crate. Writing pub(in crate::http) scopes visibility to the exact crate::http subsystem:
mod http {
pub mod h2 {
pub mod frame {
// Visible anywhere inside `crate::http` (including `http::client`),
// but hidden from `main()` at the crate root:
pub(in crate::http) fn encode_ping(id: u32) -> [u8; 4] {
id.to_be_bytes()
}
}
}
pub mod client {
pub fn send_ping(id: u32) -> [u8; 4] {
// `http::client` is a descendant of `crate::http`, so it can call `encode_ping`:
crate::http::h2::frame::encode_ping(id)
}
}
}
fn main() {
let bytes = http::client::send_ping(0x0102_0304);
println!("Encoded ping bytes: {bytes:02X?}");
}
Encoded ping bytes: [01, 02, 03, 04]
Error: Specifying a Non-Ancestor Module in pub(in path) (E0742)
Attempting to specify a sibling module that is not an ancestor of the defining module fails with compiler error E0742:
// ❌ does not compile
mod alpha {
pub mod sub {}
}
mod beta {
// Error: `crate::alpha` is not an ancestor of `mod beta`!
pub(in crate::alpha) fn helper() {}
}
fn main() {}
error[E0742]: visibilities can only be restricted to ancestor modules
--> src/main.rs:7:12
|
7 | pub(in crate::alpha) fn helper() {}
| ^^^^^^^^^^^^