1

I have the following code in src/

main.rs
a.rs
b.rs

Here's the code:

main.rs

    mod a;
    mod b;
    
    use crate::a::Summary;
    use crate::b::Person;
    
    fn main() {
        let p = Person{ first: "John".to_string(), last: "Doe".to_string() } ;
        sum(p) ;
    }
    
    fn sum(summary: impl Summary) {
        println!("{}", summary.summarize()) ;
    }

a.rs

    pub trait Summary {
        fn summarize(&self) -> String ;
    }

b.rs

    use crate::Summary;
    
    pub struct Person {
        pub first: String,
        pub last: String,
    }
    
    impl Summary for Person {
        fn summarize(&self) -> String {
            format!("{}, {}.", self.last, self.first)
        }
    }

What I don't understand is how does "use crate::Summary;" not cause a problem in b.rs? It should be "use crate::a::Summary;" or even "use super::a::Summary;", but for some reason use crate::Summary works. Is there some kind of funky search logic being applied here under the hood?

Herohtar
  • 5,347
  • 4
  • 31
  • 41

1 Answers1

2

Items defined without a visibility specifier are available to the module that they're defined in and all of its sub-modules.

Since a and b are submodules of the crate root module, they can access the Summary object that was imported via a use declaration in main into the crate root module.

hkBst
  • 2,818
  • 10
  • 29
Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
  • I would nitpick the wording to be "Items defined *or imported* ...", since `use x`/`mod a` isn't really a definition, but the visibility rules apply the same. – Jeremy Meadows Jul 26 '22 at 19:34
  • It's not a visibility issue that I'm questioning. It's the pathing. Summary is defined in a, therefore its path is crate::a::Summary. I just don't understand how only crate::Summary works, when that's not even a valid path. – John Caruso Jul 26 '22 at 23:29
  • @JohnCaruso The type's original definition is in `crate::a`, but you can `use` paths to bring them into the current scope. Whether you think of this as "importing" or "exporting" (in the case of `pub use`), the type `Summary` is available as `crate::Summary` since it was brought in via `use crate::a::Summary;`. And then, as described in this answer, sub-modules can access anything in its parent modules regardless of visibility. – kmdreko Jul 27 '22 at 00:29
  • I see. Thank you for clarifying this point! I think this is where a lot of the module confusion comes from. – John Caruso Jul 27 '22 at 01:06