Is `mod.rs` the right name for the directory owning module?


#1

I’d like to register a couple of problems with current foo/mod.rs convention.

  • mod.rs ends up lexicographically in the middle, but usually it is among the more important files because it presents a high-level API of the module. So this complicates code exploration a bit: you can’t instantly find mod.rs on github, for example: https://github.com/rust-lang/cargo/tree/master/src/cargo/ops. It’s interesting that Python’s __init__.py nicely dodges the problem, because of the leading __. Of course, if you use an IDE, it can color-code and move mod.rs to the top (we’ve added this today), but you don’t always use an IDE.

  • @briansmith also listed a concern that having a gazillion of files named mod.rs is inconvenient, because you can’t easily find the file by name. I personally don’t feel this particular problem, because any tool I use which can find files by names allows me to filter by parent directory as well. But at the same time we have special code in IntelliJ to include directory name in the name of the tab with mod.rs, because plain mod.rs is not very helpful.

And I think in theory we can add a new convention, like foo/__mod__.rs or foo/_foo.rs, in a backwards compatible way. I am not sure that it’s worth doing this though…


#2

The obvious alternative is foo.rs and foo/child.rs. We used to have this and we changed it, but many have since agitated to have it brought back. IIRC the main reason we changed it was because it felt confusing to have the “main content” of the module be in a different directory from its children.

There is some precedent, I believe npm supports either foo.js or foo/index.js.


#3

I’ve always thought __init__.py was a little verbose on the name and strange to newcomers to Python. It also matches the name of the constructor __init__(), which for some reason just seems weird.

Would you also change main.rs and lib.rs to have _'s?

The intellij-rust highlighting feature feels like a good solution.


#4

Me is pro foo.rs :slight_smile:

  • many buffers named mod.rs when editing with in emacs, not very ergonomic…
  • the rest of the modules are named after their module names, those can’t – why make an exception
  • inconvenient when opening a file from a project since you need the parent folder + mod.rs to discriminate properly
  • need to rename the file when going from foo.rs to foo/mod.rs, you can’t just move it
    • sometimes git doesn’t detect that properly if you’ve also edited the file

I don’t care much for the lexicographical order but I’d rather we didn’t use _ prefixes. IDEs and editor plugins can deal with that. (+1 to highlight foo.rs and/or put it at the top of the file list)


#5

Yes, I actually use explicit #[path]s in my code to rename <module>/mod.rs to <module>/<module>.rs, for example https://github.com/briansmith/ring/blob/4410207a4ec399241209a69e979bcd3ceb93ee1d/src/lib.rs#L140-L144. Unfortunately, a recent version of Rust broke this so I had to add this to the top of lib.rs:

#![allow(legacy_directory_ownership)]

I’m not sure what the solution is.

I’m thinking about reorganizing my code to use dotted filenames for each module, all in a single directory level.

Before, three directories for three files, three files named mod.rs:

submodule1/sub-submodule-1/mod.rs
submodule1/sub-submodule-2/mod.rs
submodule2/mod.rs

After, three files in one directory, every file has a unique name:

submodule1.sub-submodule-1.rs
submodule1.sub-submodule-2.rs
submodule2.rs

I believe this can be done with #[path] already as well.


#6

We can definitely do <module>.rs as the owner. We can’t do <module>/<module>.rs because modules with submodules of the same name certainly exist.

I see allowing <module>.rs to have submodules as just making things more consistent. Surprisingly (to me), inline modules can already have submodule files:

mod foo {
    mod bar; // at $PWD/foo/bar.rs
}

#7

Using “unix as IDE” I dont have any problem with using mod.rs. I open files by typing their names on the terminal. And on github (like on any other website) I use ctrl+f if I can’t find something instantly. __ is verbose and makes you wonder whether its some artifact of an automated tool (on UNIX, its standard to start hidden directories with a dot for example). That’s at least what I thought it was when I first encountered it in python until much later. I personally find it ugly as well. Of course everyone has different tastes, so you’ll certainly find people who think of the opposite.

I think that improving IDEs to automatically highlight it is a good idea. I wouldn’t like a change in the language. It should be the last resort, not the first thing to try.

And if you personally don’t like mod.rs, you can easily just get rid of it by doing what @briansmith proposed. So its nothing that should stand in your way!


#8

I think this is what this PR is about, right?


#9

Yes. Going to write an RFC for it, but its orthogonal to the other changes to the module system.

My workflow also favors mod.rs. I also develop in Rails, and Rails’ autoloading favors a foo.rb and foo/ approach. My completions get confused about having both foo and foo.$EXT in the same directory. Meanwhile, I use Ctrl P with vim, and it shows the complete path to the file, so I am never confused about which mod.rs I am opening.

I’ll probably keep putting my mod files at mod.rs, but I definitely see how other peoples’ workflows favor a different approach. Given that inline modules can already have submodule files, the current system just seems inconsistent.

I don’t think we should prefer any sort of __ approach.

One of the most compelling arguments in favor of the other approach (which is independent of workflow) is that it matches the module path intuition better - self:: vs super:: now mirrors which director you’re in.


#10

A useful thing for RFC to do would be to document how current system regarding directory owning modules actually works. I have the impression that the current systems is basically “what was historically implemented in rustc”, because I’ve found quite a few inconsistencies when I looked at it closely while working with modules in IntelliJ Rust (I think that the legacy_directory_ownership change is actually the result of one of my bug reports). And it would be nice to find a solution for @briansmith problem!


#11

I just want to say that M-x toggle-uniquify-buffer-names is your friend here.

Oh and since I know you use emacs, M-x rust-promote-module-into-dir.

(This post is not meant to invalidate the broader point, since some people persist in not using emacs.)


#12

Thx for the pointers! Didn’t know about the module promotion function.