When if ever do pub and pub(super) have different semantics?

Viewed 157

Rust has support for both pub and pub(super). pub makes it so the parent module can access an item... and pub(super) seems to also do exactly the same thing. I've tried playing with the example below, and swapping pub and pub(super) seems to have no effect:

#![allow(dead_code)]

mod outer {
    pub(super) fn outer_foo() { inner::inner_foo(); }
    mod inner {
        pub(super) fn inner_foo() { println!("hello world!"); }
    }
}

fn top_level_foo() { outer::outer_foo(); }

Why would you ever use one over the other?

Playground link.

1 Answers

In your example, if you change your inner module to be public, then the difference would become clear.

For example, this works because outer::inner::inner_foo is visible from the main module:

#![allow(dead_code)]

mod outer {
    pub(super) fn outer_foo() { inner::inner_foo(); }
    pub mod inner {
        pub fn inner_foo() { println!("hello world!"); }
    }
}

fn top_level_foo() { outer::outer_foo(); }

fn main() {
    outer::inner::inner_foo();
}

If you kept inner_foo as pub(super) it would've been only visible from the outer module (because super refers to the super-module, outer in the case of something inside inner), hence the above code wouldn't compile and you would see this error:

   |
13 |     outer::inner::inner_foo();
   |                   ^^^^^^^^^ private function
   |
note: the function `inner_foo` is defined here

Notice that pub can also take crate as an argument, making the function public within the crate itself, but not to other crates.

Related