modulerustprivateclass-visibility

How to hide sibling modules from each other in Rust?


I have a Rust module breakfast containing two sub modules egg and bacon. The breakfast module must know about egg and bacon, but the two children do not need to and therefore should not know about each other.

This is what my code looks like now. The breakfast gets made, but unfortunately egg and bacon can access each other.

mod breakfast {
    pub fn make_breakfast() -> String {
        format!("{} and {}", egg::EGG, bacon::BACON)
    }

    mod egg {
        pub const EGG: &'static str = "egg";
    }

    mod bacon {
        pub const BACON: &'static str = "bacon";

        // Oh no! The bacon knows about the egg!
        // I want this to be a compile error.
        use super::egg::EGG;
    }
}

Can I hide the siblings from each other somehow, perhaps by using visibility modifiers or by restructuring the modules? Or is the unneeded visibility something I should accept?

In reality, the modules are in separate files, but I put them in one here to make a clearer example.


Solution

  • This is by design:

    Rust's name resolution operates on a global hierarchy of namespaces. Each level in the hierarchy can be thought of as some item. The items are one of those mentioned above, but also include external crates. Declaring or defining a new module can be thought of as inserting a new tree into the hierarchy at the location of the definition. [...]

    By default, everything in Rust is private, with two exceptions: Associated items in a pub Trait are public by default; Enum variants in a pub enum are also public by default. When an item is declared as pub, it can be thought of as being accessible to the outside world.

    With the notion of an item being either public or private, Rust allows item accesses in two cases:

    • If an item is public, then it can be accessed externally from some module m if you can access all the item's parent modules from m. You can also potentially be able to name the item through re-exports. [...]
    • If an item is private, it may be accessed by the current module and its descendants.

    For further information on this, please consult the relevant chapter of The Reference