5 ms·
But the module system doesn't ignore the directory structure. It is designed to mirror it! Instead, the author points out that the module system ignores undecl
by Rusky 6y ago
But the module system doesn't ignore the directory structure. It is designed to mirror it!
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.
- nicoburns 6y agoI don't understand the desire to exclude files using mod. If you are including code from that file via use, then your build will still be broken. And if you're not, then the files would be excluded from the build anyway.
- justinpombrio 6y ago> And if you're not, then the files would be excluded from the build anyway. 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`.)
- nicoburns 6y agoIt doesn't have to be. It could default to be compiled if used and not being compiled unless use'd. And in the rare case that a trait impl or similar in a module without importing from that module, then you could use `mod`.
- svrb 6y ago> then the files would be excluded from the build anyway 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!
- Rusky 6y agoThink about the `git stash` use case. The goal is to go from a messy, WIP state that may or may not compile, back to a more stable, probably-working state represented by a commit. 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.
- riffraff 6y agoFWIW, if you have a new file in WIP state and have changes related to it that you want to stash it might be better to `git add` it so that it gets stashed/unstashed together with the other related changes.
- nicoburns 6y agoIf you run git stash with the -u option (`git stash -u`), then it will also stash untracked files. IMO leaving uncommitted/unignored files around is asking for trouble. It's far too easy to accidentally delete or commit them. Why not have a prefix that you use for these files, and use a wildcard gitignore?
- 6y ago
- dataangel 6y ago> Interaction with partial, in-progress programs. People wanted to be able to comment out `mod` declarations to temporarily exclude files from the build. 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.
- MrBuddyCasino 6y ago>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.
- JoshTriplett 6y agoThere's still some interest in fixing it in a future edition, if we can find the right design that won't create a substantial amount of churn or pitfalls. 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.
- MrBuddyCasino 6y ago
- wrs 6y agoYes, I know — I’m criticizing the article, not the module system. None of the reasons you mention are demonstrated in the example given, which would be much more straightforward if the module system just followed the filesystem automatically, as the author rightly points out beginners tend to expect it to. Asking people to have an “open mind” and then just showing them the complicated way to do a thing they expect to be simple isn’t very motivating.