Cargo is the bundled package manager and build tool for Rust. In practice it is the user interface of Rust. Its stellar ergonomics have made it one of the critical selling points of Rust overall. Most "why I fell in love with Rust" testimonials include praise for Cargo. Cargo is a one-stop shop providing a unified experience from adding a dependency, through identifying available versions, resolving a set of transitive dependencies, to building and testing the actual artifacts. Following Conway's law this unified experience is backed by a monolithic code base. User facing improvements often involve changes across many different modules. Furthermore code often accidentally relies on details of how other parts the code work. Attempts to break up the monolith often get stymied by the number of implicit details that need to be public for the existing code to work correctly.
Eventually cargo should be a thin wrapper wiring together independently tested and maintained crates for doing the internal logic. This goal is most helpful because the ever-growing cargo monolith continuously gets harder to maintain and develop. But also, many cargo plug-ins or wrappers are fundamentally "work as if cargo had slightly different functionality" which would be much easier to develop and maintain if the portions of cargo's functionality they want to preserve were available as independent libraries. At this time this goal appears impossibly far off. But this is the kind of work where the goal will seem impossible until suddenly it's almost done. The only thing we can do is find components that can be split out and do so. I am working on the resolver.
The dependency resolver solves the NP-Hard problem of taking a list of direct dependencies and index of all available crates and returning an exact list of versions that should be built. This functionality is exposed in cargo's interface as generating/updating a lock file. There are many ways two crate versions can be incompatible. The current resolver relies on concrete datatypes from other modules in cargo to determine if a set of versions have any of these problems. It is therefore difficult to abstract and separate the existing resolver from the code base. On the other hand, because the problem is NP-Hard it is not easy to tell what code changes break loadbearing performance or correctness guarantees. Which makes any change to the current resolver in situ extremely treacherous. Nonetheless, big changes are required: there is lots of new functionality that will affect the resolver and the existing resolver's error messages are terrible.
Who could be affected.
The previous section mixed together the interests of various different customers that I'd like to try and tease apart here. I'm only gonna focus on those affected by the resolver changes, other work on library-ification may benefit other users.
The Cargo Team