Does "private in public" work with paths?


#1

Hi!

Today I’ve noticed that the following compiles without warnings:

mod a {
    pub use self::b::{make_s, consume_s}; // S is effectively private to a
    mod b {
        pub struct S;
        pub fn make_s() -> S { S }
        pub fn consume_s(_: S) { }
    }
}

fn main() {
    let s = a::make_s();
    // typeof(s) == S
    a::consume_s(s);
}

Is it supposed to be so? Roughly equivalent code causes public in private error…

mod a {
    struct S;
    pub fn make_s() -> S { S }
    pub fn consume_s(_: S) { }
}

fn main() {
    let s = a::make_s();
    a::consume_s(s);
}

#2

Yes. The current rules are very simple and local - if something is marked as pub (like S in the first example), then it’s considered public, if something is not marked as pub (like S in the second example), then it’s not considered public. S being “effectively private” due to some intermediate private modules is not taken into account. RFC 136 is the normative document. Also see the discussion in [lang-team-minutes] private-in-public rules about tweaking the rules in various backward compatible ways.


#3

Yes that is the correct behavior, because struct S is marked pub and not pub(super).

I agree that it is confusing.


#4

(Sorry to resurrect an old thread). How will this kind of thing change in Rust 2018?