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);
}
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.