Modules RFC: separating local module into its own crate


#1

The current module RFC suggests separate namespace for crate’s own modules and external crates’ modules.

I have doubts about this goal:

  • I’m not convinced that the distinction between crate’s own modules and other modules is important in the first place. Most of the time, it doesn’t affect anything. There’s no decision to take depending on this. The only exception are orphan rules, but compiler already shouts loudly about this, and the information is needed at trait/type level, so module use is not exactly where it’s needed.

    It’s true that users generally group use of own and 3rd party modules separately, but I think that’s mostly aesthetics. I’d continue to do that even if paths were required to use local::.

  • It creates a new failure mode if the author doesn’t remember where every module is from. When writing paths, it requires author to know where module comes from. So instead of informing, it will require authors to keep more (IMHO irrelevant) information in their heads.

  • The distinction gets blurry when it comes to crates from the same workspace. It’s technically an external create, but still internal to the same project.

  • I am concerned about the downside when “upgrading” a crate-local module to a workspace crate.


I’ve realized that most of the code I write goes through an evolution phase:

  1. I a feature as a function/type private in a module or top of the crate.
  2. When it grows bigger, I move it to its own module.
  3. When it grows even bigger, I move it to its own create inside Cargo workspace.

I find the step 3 very important, because it enforces very good separation of crate’s dependencies and helps structuring dependencies as a tree, rather than a anything-depends-on-everything cyclic mess.

Currently the step 3 is lovely, because I can replace mod foo with extern crate foo and everything just works! Unfortunately, the proposed use local:: syntax goes against this. Upgrading local module to a local workspace crate requires changing of all use prefixes to remove local::. That’s annoying. It creates friction, and I don’t see any value added. I’d still consider that my local module, it’s going to be in my own workspace in my own repository.


#2

I believe the main point you seem to(?) have overlooked is that this change unifies path behavior in the root module and its submodules, which is a bit of a cliff for new users once they add a new file.

This is an interesting tradeoff to be aware of, though.