It's a tradeoff: if you make the file the language's compilation unit, then you can't have "circular imports" to allow end users divide their code in an ergonomic manner with fewer "arbitrary" restrictions. We can argue all year on whether Rust settled on the right side of that trade-off.
I'm just surprised that no one has (to my knowledge, anyway) tried this even experimentally. Wouldn't the potential build speed improvement be worth at least trying out the one-file-per-crate strategy?
> I don't love how the dependency graph looks
After adding this complexity to the project, yes, some of the crates are building in ~3s, if they are the only ones that needed to be rebuilt.
Meanwhile, in a Java project there is none of this artificial crate splitting. Sure, Java projects have other nonsense, but they don't force you to split up projects into tiny pieces to get decent compile times.