In responses to the latest modules RFC there is some push back against automatically loaded modules, so I’d like to propose a refinement to the autoloading idea.
Only modules that are used are loaded.
(where use means either explicit mod as it is currently, and/or appearing in any use path in the project).
This means that a stray file on disk won’t be automatically included in the project. There has to be at least one use somewhere that refers to it in order for the file to be included in compilation. If you rely on hiding a module by commenting out mod foo, you can do the same by commenting out use foo. #[cfg] mod foo is satisfied by #[cfg] use foo.
Changes from current behavior:
- You don’t need
mod fooif there is anyuse foooruse foo::barstatement. For new users it will appear as if all modules exist, and are ready to use. This is very close to behavior of other languages havinginclude/require. - If a module only has
impl, and no items from it are used explicitly, you’ll need touseit explicitly (or keep amod).
Advantages:
- Untracked/unfinished/garbage files aren’t surprisingly included in the project
- Source code still describes its own module hierarchy, and it’s still possible to comment out a module by editing project’s source code.
- Removes confusion between relative
mod fooand absoluteuse path::to::foo, both having confusingly similar effect to novice users.
Downsides:
- Relative
mod foobecomes absoluteuse path::to::foooruse self::foo - Visibility of modules is not explicit (it’s
pub(crate)by default, and other proposed mechanisms for exporting may be needed). - unused import lint may need rethinking