Why are a structures in the crate root not private?

mod users {
    pub struct Admin {
        pub id: i32,
    }
}

// Why does this structure not obey the rules of module privacy ?
// After all, Admin is also defined in the module 'crate::Admin'
struct Admin {
    id: i32,
}
fn main() {
    let user1 = users::Admin { 
        id: 1,
    };

    let user2 = Admin { 
        id: 2,
    };
}

Can you say what error are you expecting, and on which line?

crate::Admin is a distinct type from crate::users::Admin.

To see this, try this:

let u1: crate::users::Admin = crate::Admin { id: 0 };

And see that there's an error.


Additionally, items in the crate root are not treated specially. The crate root is just a module with a special name.

In a module, every item can see the private contents of items in the same module.

1 Like

I know.

Are the elements declared in the same module public by default for each other ?

mod users {
    struct Admin {
        id: i32,
    }
    // ok
    fn test() -> Admin {
        Admin {
            id: 1,
        }
    }
}


fn main() {

}

If this is the case, then why does it work?

mod users {
    struct Admin {
        id: i32,
    }
    // That's working. But why is there no error - struct `Admin` is private ?
    fn test() -> crate::Admin {
        crate::Admin {
            id: 1,
        }
    }
}

struct Admin {
    id: i32,
}
fn main() {
    // error - struct `Admin` is private
    let user1 = users::Admin { 
        id: 1,
    };
}

Yes, items declared in a module (including the crate root) are always visible to other items in the same module or in its submodules.

So for example an item declared in the crate root, i.e. the module crate, is visible to items in the module crate::users, because crate::users is a submodule of the module crate.

This is not just a "default" but how it always works. You can only make items more visible than this, not less. If you really want to make something less visible, put it in another submodule. For example if you move something from the crate root to a different submodule crate::foo then it will no longer be visible to code in the module crate::admins, because crate::admins is not a submodule or crate::foo.

4 Likes

Privacy in Rust works only in one direction — parent module can't see private items in submodules. OTOH, modules can see private items in the same module and private items in all of their their ancestors.

pub(crate) and pub(in path) can change that a bit. Also it's possible to publicly re-export pub items from other modules.

What is OTOH modules ? :smile:

On the other hand, modules ...

1 Like