Modules RFC: `use` is `mod`


#1

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 foo if there is any use foo or use foo::bar statement. 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 having include/require.
  • If a module only has impl, and no items from it are used explicitly, you’ll need to use it explicitly (or keep a mod).

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 foo and absolute use path::to::foo, both having confusingly similar effect to novice users.

Downsides:

  • Relative mod foo becomes absolute use path::to::foo or use 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

#2

One feature of the current mod syntax is that you can order the inherent impl’s in the docs by loading your modules in the correct order. Do you propose to instead tie this order to the use order in the modules parent module?


As anecdata for how bad this can be: my crate roaring has a total of 15 leaf modules, out of those only 6 are currently involved in use expressions, the other 9 will need to have an extraneous use added to keep them loaded. It doesn’t matter so much as I would need something manually specified to control the doc order anyway, but maybe there are people with a similar code division policy that don’t care about doc order so much.


#3

I have a lot of gripes about order of things in rustdoc — not just impls, but also organization of types and traits they belong to. So short term it’ll probably be the order modules were first seen in use statements (so if you just replace mod with use in the crate root, it will work), but a proper solution for this may be something else entirely (like doccomment annotations, rustdoc config/table of contents).

The other way to look at it is that it will be 6 declarations fewer overall (use < use + mod), and you only need one kind of declaration, not two (that’s a big win for new users).


#4

This.

"use implies mod" is strictly an improvement, saving many many mods, and just because in some cases it doesn’t, is not a big problem.