Instead, the author points out that the module system ignores undeclared source files.
There are a couple of practical reasons that prevented us from automatically deriving the module tree, as part of the 2018 edition changes to the module system:
* Interaction with partial, in-progress programs. People wanted to be able to comment out `mod` declarations to temporarily exclude files from the build.
* Interaction with version control, e.g. `git stash`. Similar to the above, people want to exclude untracked files from the build when their corresponding `mod` declarations are stashed.
Notably, this is basically the same set of problems people face when using globs in their build system. Maintaining an explicit list of source files can be slightly tedious, but it avoids a lot of surprising behavior in the edge cases around removing files. Rust's list just happens to be distributed throughout the source files, rather than consolidated in a build system file.
They aren't though. Even if the module isn't `use`d, it's still compiled.
(And it has to be. If nothing else, there could be a trait impl buried in the module, which gets shared without `use`.)
Why would this be the case? Under this model, are we not allowed to have public symbols anywhere in a library but at the root? In other words, why should I have to "use" something from a module from elsewhere in this crate to get it to build?
I'm already hopelessly confused by your system. The current model is simple, correct, and efficient. No wonder people hate it so much - it's human nature to hate the unfamiliar!
That messy state may include a new, partially-implemented module file. By default `git stash` will leave it alone, because it's untracked. But `git stash` will also remove its corresponding `mod` declaration, and any uses of it, all at once.
Now say you want to build and run. If that WIP module file gets picked up automatically, it will probably break the build! It may simply be incomplete, or it may depend on some of those stashed changes, or whatever else. Even if it happens to typecheck, now you're assuming that it's all dead code- but it may have some public API (including trait impls!), and still be included in the build!
In fact, we already have a taste of this kind of problem, ever since Cargo started running build.rs scripts automatically, even without a `package.build` key in `Cargo.toml`. If you add a build script with some build-dependencies, run `git stash`, and then build, the build script will fail to compile!
Perhaps you could argue that this is a deficiency in `git stash` that Rust shouldn't have to be concerned with. But if `git stash` removed untracked files as well, that would simply break other use cases instead! For example, I often have a few extra files laying around, which I don't ever intend to commit or .gitignore- sample inputs or outputs, short-term todo lists, or other scratch-pad-like data. Ideally `git stash` would leave those alone- but it's hard for git to tell those apart from the problematic cases above.
That is, my own personal workflow poses essentially zero risk of deleting or committing those files, so "quit using the file system the way I've always used it" is no less of a stumbling block for me than "maintain `mod` declarations" is for you.
We simply haven't found an approach that doesn't step on someone's toes, so the one that Rust was already using from the 2015 edition stuck.
Except the current system actually has the opposite effect -- working with partial programs is actually worse from the standpoint of using rust analyzer. Newbies like myself start writing a new source file and expect that completion and other features will work right away.
> Interaction with version control, e.g. `git stash`. Similar to the above, people want to exclude untracked files from the build when their corresponding `mod` declarations are stashed.
They can just stash the file as well.
This strikes me as making the whole system harder for new people to understand just to smooth over edge cases for power users that definitely have the ability to come up with workarounds.
This is exactly what it is, and due to inertia it won't ever change. At this point, there is no other choice but to either accept it or find peace in smth else.
The 2018 module system was already a substantial redesign, and because of that, we chose to carefully minimize churn to existing programs (which involved two iterations on the design before the 2018 edition released); the vast majority of programs designed for Rust 2015 will Just Work with the 2018 module system.
A future edition could very carefully allow for filesystem-based modules, and focus primarily on that without having to deal with other module system changes at the same time. I can imagine some possibilities that might achieve that, if someone has the bandwidth and diligence to work on it and test it.
Just to be clear, I have the highest respect fo the Rust core team, I've followed some discussions and you guys are going above and beyond carefully weighing all the pros and cons, often to an exhaustive degree.
I feel the main strength of Rust is also its biggest weakness: alway striving for the perfect, platonic ideal solution, and going the extra mile to get there, which then might discard a much simpler but slightly less powerful solution. Often thats a good thing, not sure it was warranted for the module system. I remember there were different opinions in the core team, Aaron being a proponent of the simple version I think.
At a minimum, this could be an off-by-default configuration. Ideally, it would suppress errors caused by these extra files, and downgrade errors caused by missing `mod` declarations to warnings, with a quick-fix to add the declaration.
> They can just stash the file as well.
This is an option, but it's not clear-cut whether it's a better one. See my other comment: https://news.ycombinator.com/item?id=23890842
> This strikes me as making the whole system harder for new people to understand just to smooth over edge cases for power users that definitely have the ability to come up with workarounds.
This certainly was not the goal. The goal of the 2018 module system changes in general was to make the module system easier to learn than it was before; this aspect was simply retained as-is because we couldn't figure out how to make it better without making existing aspects worse.