Lib root `pub use` will only work if the mod is also pub


Hiya :slight_smile:

So I want to make a nice and tidy interface for my library crate. So instead letting a user have access to sub-modules, I want them to be able to reach structs/etc from the library root (

mod sh2;
pub use sh2::Sh2;

And in the client code, I try to access about thusly:

use libname;
let sh2 = libname::Sh2::new();

However, this will fail with:

error: module sh2 is private

Which was the whole point.

Doing a pub mod sh2; makes things compile, but we loose the encapsulation.

So was this by design? Am I doing something wrong?


It should work if Sh2 is public, even if sh2 is private.

mod internal {
    pub mod exposed {
        pub const FOO: u32 = 1;

pub use internal::exposed;


The same thing works for me. Does your code have use libname instead of extern crate libname?


cargo new libname

cat > libname/src/ <<-'EOF'
    mod sh2;
    pub use sh2::Sh2;

cat > libname/src/ <<-'EOF'
    pub struct Sh2;
    impl Sh2 {
        pub fn new() -> Self {

cargo new --bin ties

cat >> ties/Cargo.toml <<-'EOF'
    libname = { path = "../libname" }

cat > ties/src/ <<-'EOF'
    extern crate libname;
    fn main() {
        println!("{:?}", libname::Sh2::new());

cargo run --manifest-path ties/Cargo.toml


No, in my case Sh2 is pub. I should think Sh2 should always be pub for things to even work. You can’t access a private struct in a pub mod I don’t think.

I’m sure the examples in say ‘the book’ work, in which submodules of library submodules can be exported in this way. But specifically in the library root ( this does not seem to work.


Could you share the full code?


Thanks for your thorough reply. And sorry to waste your time, I’m an idiot. There was a use libname::sh2 in the root of the client lib. I should have made my own stripped down example first.

Very much thanks for the help though!