In Rust, the ability to conditionally include a module (i.e. #[cfg(feature = "foo")] mod foo;) is important. With “module discovery”, this is no longer possible.
I want to note something a lot of people (including myself!) have tended to miss: Rust is not the only language to require explicitly including module files. C/C++ have the mess of header files required, and compiling and linking each individual source file. Python and JavaScript each require including modules/files explicitly as well.
Interestingly enough, even Java doesn’t do automatic file discovery. If you’re using javac directly, you have to compile each .java into a .class and then bundle them all into the .jar. It’s just that all common build tools automatically do this for every file in a directory.
rustc, the actual Rust compiler, actually does the module discovery by way of the mod declarations. The cargo build tool only has to invoke rustc on the root .rs file.
The difference is that with #![cfg] the module still has to parse, whereas it doesn’t with #[cfg]. If, e.g., you had a module that contained optional async.await code, parsing it even with #![cfg(FALSE)] will fail on any currently stable compiler. Alternatively, if the mod declaration is #[cfg]d, you can restrict parsing of that module to users who opt in, and still support earlier compilers for those who don’t.
And, is it possible to change rustc’s behaviour so that codes that contain async.await can be compiled successfully with #![cfg(FALSE)] (declared in the module)?