Distinctions between extern crate, mod, use and pub use often hard for newcomers
Paths are sometimes absolute, sometimes relative
The top-level namespaces mixes in crate names from external crates, and the contents of the current crate
Makes moving code from a library out to an external crate annoying
mod.rs is a bit weird and confusing; it makes refactoring more painful than it should be
The privacy system can be very confusing and hard to navigate
The default rules about who can see private items are, to many, not intuitive and hard to remember
The mixture of privacy and re-exports can make it pretty hard to know how exposed a particular item is
pub(restricted) helps
It’s confusing than an inline mod { .. } declaration doesn’t automatically inherit the bindings from the outer scope(equivalent to use super::*)
Tedium/redundancy issues
extern crate is redundant with Cargo.toml
mod declarations are often redundant with the file system
Observations on the current module system
Coupling
Ties together three things:
Files
Namespacing
Privacy
However, the coupling is incomplete; there are various escape hatches that let you break the connections between these three things, and that’s part of where confusion arises.
Use-cases for features
pub use
Re-exporting upstream types(when you don’t want your clients to have to deal directly with one of your public dependencies)
Using a submodule for organization and/or privacy, but not for namespacing
preludes, or otherwise making access more convenient
Crucially, these are re-exporting items already publicly accessible from a different path
Tricky use-cases we(may) want to retain
Attributes on extern crate declarations
macro_use
Are there others?
Attributes on mod declarations
Privacy
#[cfg]
Uses of modules that couple files and privacy, but don’t couple public namespacing
e.g., define a submodule for building out a type and a bunch of operations on it with privacy, but then re-export that type in super
Of course, these still affect“internal” namespacing, which also leads to multiple paths being usable inside a module to reach the same item.
Privacy between modules of a crate
This means, for example, that having a totally orthogonal“public item hierarchy” through explicit export statements is not clearly workable
How to get the coupling we want, and avoid the ones we don’t
Definitely want to couple files and privacy
“Coupling” filesystem and namespacing doesn’t have to be totally 1-1 correspondence
Just need the ability to easily predict the API hierarchy from running tree
(and not the other way around)
One idea:
if you leave off mod.rs then the submodules are pub use self::sub::* and are themselves private
Problems we (might) want to solve
Observations on the current module system
Tricky use-cases we (may) want to retain
How to get the coupling we want, and avoid the ones we don’t