points by comex 5 hours ago

You’re thinking at the wrong scale. Rust allows circular dependencies just fine, within modules in a crate. And it’s extremely common for modules within a crate to have at least some circular dependencies - type X has some method (trait impl of inherent impl) that mentions type Y, and type Y has some method that mentions type X. In fact, I would be surprised if you could name me a single medium-size-or-larger popular crate that doesn’t have at least one cyclic reference between modules! Though, sometimes those cycles are not essential and could be avoided by splitting up modules. But sometimes they are. Either way, in C or C++ those modules would probably be their own compilation units.

That said, you also run into related parallelism blockers without cycles. For example, the orphan rules force most trait impls for a type to be in the same crate as the type definition. Also, a module which has no source-level cycles will often have cycles after monomorphization. In this case, Rust doesn’t prevent you from splitting the code into crates like it does with source-level cycles, but you do lose most of the actual codegen parallelization unless you can switch from generics to trait objects.