Cargo features are separate from Rust language features, and Cargo can’t nicely set language features (overriding compiler flags for the entire build is a blunt tool), so there’s a hypothetical inadequacy, but I don’t think that’s the reason.
Not having code before main is a very useful property for a low level language.
It means it’s easily interoperable with C. It means it can be used in a static library linked with any other programming language. It means it can work easily as a dynamic library used as a plug-in in lots of native software, and in all these cases every function you export from Rust will just work.
If Rust could depend on some global code automagically run outside of main, then it could break if that magic isn’t always properly set up. It would mean that externally calling some random Rust function (from C, from other language’s FFI, from plug-in host) could hit Rust by surprise in a semi-uninitialized state with broken globals.
OP’s motivation: running
env_logger::init() for every test is a real problem. BUT I think it’s better to solve that one with test frameworks that have setup and teardown, without adding a potentially problematic feature to the entire language: