# Revisiting modules, take 3

**URL:** <https://internals.rust-lang.org/t/revisiting-modules-take-3/5715>\
**Category:** language design\
**Created:** [August 4, 2017, 9:06pm UTC](https://internals.rust-lang.org/t/revisiting-modules-take-3/5715 "2017-08-04T21:06:02Z")\
**Posts on this page:** 1\
**Showing post:** 23

<div class="post-metadata">

**Author:** ![est31](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/est31/32/2551_2.png) [@est31](https://internals.rust-lang.org/u/est31)\
**Post date:** [August 5, 2017, 2:20am UTC](https://internals.rust-lang.org/t/revisiting-modules-take-3/5715/23 "2017-08-05T02:20:54Z")

</div>

Thanks for writing up the next iteration. [My reply to the last iteration](https://internals.rust-lang.org/t/revisiting-rust-s-modules-part-2/5700/4). The rate of parts I agree with / parts I disagree with has mostly stayed the same.

I'm still strongly against deprecating explicit `mod`. That's a bad idea and it means you need to open the file view (which I hate opening and which is highly inconvenient to use in larger projects) and do all kinds of hacks like defaulting publicity to `pub(crate)` (which makes stuff harder for people who want to do stricter crate privacy).

Second, I want to repeat that I'm a great fan of the concept of separating `use` from the local crate, and separating `use` from external third party crates. **The concept of `from use` is really awesome**! I'm open to any other syntax that has been proposed (including the @ notation and your proposal), as long as it keeps the separation.

I'm not really a fan of

```rust
use std::io;
mod bar {
    use io::{Read, Write}; // NOTE: No `std::`
}

```

Its definitely not nice (lets call it "bar example" below) and think it should be treated like a bug. But I do like:

```rust
use std::io;

fn foo() -> io::Result<()> {
}

```

Because it allows some shallow level of scoping without importing everything from io or having to provide an explicit list. You can easily ctrl-f for `io::` and you find everything you need!

**And I also like the "everything is an item" rule**. It keeps concepts consistent. In fact, recent movement has been to add consistency here, by adding macros to the traditional namespacing system, not to remove it. So this change would be against the general trend.

Regarding the "bar example": you have taken it as example of how "everything is an item" is bad. I don't think this is actually due to that rule, but more because `use` is _not_ consistent with other items. Because for other items, the same setup fails:

```rust
fn baz() {
}

mod bar {
    fn foo() {
        baz(); // error: cannot find function `baz` in this scope
    }
}

```

I do think we should **keep the "everything is an item" rule** , and address your issues in other ways instead:

1. Deprecate `extern crate` and let users do `from crate use` or `use @<crate>::<path>` instead.
2. I think this can be fixed by better teaching! Just expand documentation. The separation of use and mod is really great and allows you to have public modules and private ones.
3. To make the "bar example" an error which it deserves to be, you should just make `use` look into the super module for any uses. If you instead had to write `use super::io::{Read, Write};` I think this would be very obvious.

As I like the "everything is an item" rule to be kept, I don't think we need to replace `pub(use)` with `pub extern`.

> [@withoutboats](#):
>
> This introduces a firmer convention around multi-crate packages. In my survey, most multi-crate packages already conformed to this

I disagree that multi-crate projects abide the rule. In fact, multiple high quality projects don't abide by the rule:

- main rust compiler
- cargo
- servo

And there is an actual reason why they do it: the src directory is only overhead for them. The src directory makes total sense if you have a single crate project directly in the main directory of your git repo. Here you have lots of files like `README` or `.travis.yml` or `LICENSE-*` that are clearly no rust source code and where a separation is a good idea. But if you have a multi crate project, those files are already separated from the source code by the crate directory layer. There remains one sole file which gets separated: the `Cargo.toml` file. And doing this additional layer for one file is not really useful IMO.

The module system is not a hard to understand part of the language and having patterns absolutely 100% consistent over all projects shouldn't be so important that you are okay with making coding harder for the contributors of multi crate projects. I guess you'd argue that this is in order to make it easier for new contributors to join, well I don't think that understanding that there is no src directory is really a big leap.

I'm a big fan of having a consistent build system, especially considering what an inconsistent mess C/C++ buildsystems are, but this doesn't mean that there should be no way in cargo to adjust the patterns a little bit to make them best suiting.

---

_[View the full topic](https://internals.rust-lang.org/t/revisiting-modules-take-3/5715)._
