where I declare mod side_app; in lib.rs, and all items are public.
What's puzzling me is that the side_app.rs file is completely useless to my opinion: its content is (entirely):
pub mod subapp1;
pub mod subapp2;
and hence serves as a "pub mod listing" of every module located in the (first level of the) branch of the same name. I would rather call directly the two subapp modules in lib.rs.
Cannot the compiler recursively search into the crate structure to find the declared modules? If not, why?
If you want all the items in subapp1 and subapp2 to appear directly in side_app (I'm not sure if that's what you want, but it's not clear from your post), then change side_app.rs to:
mod subapp1;
mod subapp2;
pub use subapp1::*;
pub use subapp2::*;
pub mod side_app {
pub mod subapp1;
pub mod subapp2;
}
and you won't need the useless file.
The compiler doesn't search, because:
it could be slow (needs to scan directory tree instead of accessing paths directly), and speed matters for IDEs (rls) and quick feedback from cargo check.
it could be ambiguous (there can be more than one module with the same name, but different path).
There has to be mod for each file, because:
It prevents unwanted files from being included in the project by accident (e.g. old backup copies, unfinished files, leftovers from messing up git branches)
It allows conditional inclusion #[cfg(feature = "enable_foo")] mod foo;