Module thoughts 2017-08-01
  • Confusion around mod vs use vs extern crate
  • This likely arises when one’s mental model is “making a file makes a module”, and hence you expect to be able to use items from files in your project without any ceremony.
  • Similarly, adding a dependency to Cargo.toml can feel like the dep has … been added! And therefore that you should be able to use from it straightaway.
  • Conclusion: a world in which you use use to bring things into scope, full stop, seems like a big improvement.
  • Confusion around absolute vs relative paths
  • A contributing factor is surely that, when you have a submodule, you can immediately refer to it within signatures and expressions. It’s then jarring that if you want to explicitly use items from within that module, you need self::
  • It’s not really the case that signatures/expressions use “relative” paths. Rather, they use what’s in scope. But submodules are always in scope.
  • OTOH, requiring you to use a submodule to be able to name it seems unergonomic…
  • Choice of absolute paths for use
  • A big part of the argument was that absolute paths are the common case. (See also the same story in Python)
  • However, this is likely due to the large number of imports from other crates, especially std, and it’s confusing that those are “mounted at root” anyway.
  • You could imagine instead doing:
  • use vec from std, i.e. where the thing after from is always a crate
  • This clears up confusion around the root namespace
  • It also gives you more clarity about what is coming from this crate versus external crates
  • However: still need a story for ::std::vec::Vec::new() in expressions etc.
  • Maybe leading :: is repurposed to mean “crate” and can be followed by either external crate names, or crate to jump to root of the current crate?
  • Is it feasible to just deprecate this syntax?
  • use foo could then be relative (backcompat concerns…)
  • Would probably still want use super:: to be a thing?
  • Could have use top_level_mod from crate or some such as a way to jump to root
  • This opens the door to pub use for exporting submodules
  • Wasn’t a great option before due to needing pub use self::
  • What would this mean for pub(restricted), which rightfully uses absolute paths?
  • Confusion/annoyance with mod.rs
  • Just allow foo/ and foo.rs to coexist
  • Eventually deprecate mod.rs
  • There’s a possible back-compat story here:
  • Introduce and stabilize use from 
  • Deprecate use without leading self or super, instead pushing usage to use from
  • This can be done with rustfmt! Super easy to automate.
  • Checkpoint preview period, making ^ an error
  • Make use employ relative paths
  • Deprecate use with leading self

use HashMap from std::collections;
use collections::HashMap from std;
use {self, Read, Write} from std::io;

use my_sub_module::Foo;
use Foo from my_sub_module;

// shorthand:
use foo;
// for:
use foo from self;

use Foo from self::my_sub_module;
use my_sub_module::Foo;