Somebody explain pub(restricted) reexports to me


#1

Hmm, I feel a bit uncomfortable about the interdependencies between things in this module…

Ahah! I got it! Since I’m already using nightly, let’s try out pub(restricted)!! :smiley:

#![feature(pub_restricted)]
fn main() { }

mod far {

    mod outer {
        // Hoo-wee, there's a lot of stuff in this module.
        // Let's make a neat little inventory of all things
        // visible at this scope to help make sense of it all.
        pub        use far::outer::bar::hello_world;
        pub(crate) use far::outer::bar::hello_crate;
        pub(super) use far::outer::space::Bypass;
        pub(self)  use far::outer::foo::hello_bar;
        pub(self)  use far::outer::space::Planet;
    
        mod foo {
            // to help make sure the above list is complete,
            // we'll also make a point to only import things
            // indirectly from the supermodule
            use super::Planet;
            use super::Bypass;
            
            pub(super) fn hello_bar() {}
            
            fn private_stuff() {}
            fn more_private() {}
            fn no_peeking() {}
        }
    
        mod bar {
            use super::hello_bar;
    
            pub(crate) fn hello_crate() {}
            pub fn hello_world() {}
            
            fn hello_world_implementation_detail() {}
            fn hello_world_implementation_detail0() {}
        }
        
        mod space {
            pub(super) struct Planet;
            pub(far)   struct Bypass;
            
            impl Into<Bypass> for Planet {
                fn into(self) -> Bypass { Bypass }
            }
            
            fn some_util_function() {}
        }
    }
}

(Playpen: https://is.gd/YYnMIO)

Cool!!
…er, oh, wait a second :confused:

error[E0432]: unresolved import `super::Planet`
  --> <anon>:19:17
   |
19 |             use super::Planet;
   |                 ^^^^^^^^^^^^^ no `Planet` in `far::outer`

error[E0432]: unresolved import `super::Bypass`
  --> <anon>:20:17
   |
20 |             use super::Bypass;
   |                 ^^^^^^^^^^^^^ no `Bypass` in `far::outer`

error[E0432]: unresolved import `super::hello_bar`
  --> <anon>:30:17
   |
30 |             use super::hello_bar;
   |                 ^^^^^^^^^^^^^^^^ no `hello_bar` in `far::outer`

error: aborting due to 3 previous errors

I figured that pub(some::path) use x would reexport names similarly to pub use x; except in a manner that is only available to some::path. This is evidently not the case.

So… what does pub(some::path) use x; do?


#2

I don’t have much time to give a more in-depth answer right now, but FYI, you might be interested in the associated RFC: https://github.com/rust-lang/rfcs/blob/master/text/1422-pub-restricted.md


#3

I did pore over it quite a bit before posting, but was unable to find anything that addressed this (or at least, nothing using the words I might expect to see!).

I shall ask on the tracking issue if this is working as intended.

Edit: Got a quick response: One needs #![feature(item_like_imports)] to reexport non-pub items.