I'm learning about Rust, and trying to figure out the visibility rules for modules. I have the following code:
fn x() -> u8 {
5
}
struct Person {
name: String,
}
mod example {
use super::{x, Person};
pub fn foo(person: &Person) {
println!("{}", x());
println!("Person with name: {}", person.name);
}
}
fn main() {
let person = Person{name: String::from("PersonName")};
example::foo(&person);
}
Which throws the following error:
Compiling playground v0.0.1 (/playground)
error[E0446]: private type `Person` in public interface
--> src/main.rs:12:5
|
5 | struct Person {
| ------------- `Person` declared as private
...
12 | pub fn foo(person: &Person) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
For more information about this error, try `rustc --explain E0446`.
error: could not compile `playground` due to previous error
From my understanding, children submodules should have visibility to the symbols from the parent module. I'm not sure why I need to mark
Personas public.If I mark
Personas public the code executes, but my next question is, why I don't have to mark thex()function as public also, as it is used at the same place with thePersoninstance.
Inside the module
exampleit's not known that the module is only visible tosuperit also might have been reexported somewhere completely different inmain.rs:which would be difficult or even impossible to track.
A solution other than making
Personpublic is to mark the function public only tosuper:Which avoids all those pitfalls and thus compiles as you can see on the Playground
For why you'd have to mark
Personas public but notxthe reason is thatPersonappears in the signature offoo:fn(&Person)whilexdoes not.