From my experience in C there are two ways libraries deal with not being able to easily pull in their own dependencies. Some of them include their own reimplementations of lots of things (data structures, logging, error handling, date-times). Others decide to keep it simple and only implement a minimal set of functionality which limits their need for dependencies or reinventing the wheel.
Cargo letting libraries easily have their own dependencies means that many Rust libraries are very rich and fully featured. This has plenty of advantages, but the big dependency tree can be a problem in some circumstances. Crate features can sometimes help but usually not much in my experience.
I’ve seen libraries appearing in Rust which are specifically very simple and minimise dependencies (ureq is an example I like). This gives the developer the choice whether they want libraries which just do a small basic job or whether they are okay with including lots of dependencies in exchange for rich functionality. There’s a risk of segmenting the ecosystem (see also async/tokio) but it seems to be working pretty well to me.
I don't know that I have a better suggestion, but the lack of friction on adding new dependencies makes for really hairy dependency graphs. For example, I really loathed having to write this[1] when all I did was write a gstreamer plugin in Rust. I'm not even confident that I got it all the licensing right, and I surely didn't vet every single library in the graph nor will I vet every library during a future cargo-update.
In languages where adding dependencies is more difficult, I think things tend to be simpler and thus, more verifiable. But it's also simply harder. I don't know which solution I like better.
In theory, if the complexity of libraries stayed the same then pretty much the only advantage of not having recursive dependencies is a simpler license statement, and cargo-license should make that easy to automate.
In terms of checking over the code, cargo dependencies should result in less duplication and so fewer lines of code for the same level of functionality, and having it split into crates doesn’t obviously make it harder to review and Cargo.lock means the dependencies won’t change unexpectedly.
I do agree that there is a question about whether easy access to pulling in dependencies means libraries are more inclined to bloat and unnecessary complexity. But not having cargo dependencies at all would seem like a very big hammer to solve that problem. I’d much prefer to grow an ecosystem of minimal/simple libraries which don’t try to do everything and which limit their dependencies.
Actually writing the license wasn't the bad part, it was that Cargo more-or-less-silently pulled in a couple dozen different projects, which means a couple dozen different projects that a responsible software distributor "should" be vetting.
(I did use some tool like you mention, but my recollection is they were pretty crummy. IIRC they just did a dumb full dependency graph, so included stuff required only for platforms that I wasn't deploying for; also I think the output format was ludicrously verbose so I had to manually trim it down. This was a couple years ago, perhaps the tools have improved since then.)
Cargo letting libraries easily have their own dependencies means that many Rust libraries are very rich and fully featured. This has plenty of advantages, but the big dependency tree can be a problem in some circumstances. Crate features can sometimes help but usually not much in my experience.
I’ve seen libraries appearing in Rust which are specifically very simple and minimise dependencies (ureq is an example I like). This gives the developer the choice whether they want libraries which just do a small basic job or whether they are okay with including lots of dependencies in exchange for rich functionality. There’s a risk of segmenting the ecosystem (see also async/tokio) but it seems to be working pretty well to me.