From 50588a9ee37048d2c9c6571c68dc7809ebfe9815 Mon Sep 17 00:00:00 2001 From: Peter Williams Date: Mon, 23 Jan 2023 19:37:59 -0500 Subject: [PATCH] docs(ref): revise resolver duplication edits based on feedback --- src/doc/src/reference/resolver.md | 60 ++++++++++++++++--------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/src/doc/src/reference/resolver.md b/src/doc/src/reference/resolver.md index 1bcd02e2166..1e78223dd22 100644 --- a/src/doc/src/reference/resolver.md +++ b/src/doc/src/reference/resolver.md @@ -7,9 +7,9 @@ result of the resolution is stored in the `Cargo.lock` file which "locks" the dependencies to specific versions, and keeps them fixed over time. The resolver attempts to unify common dependencies while considering possibly -conflicting requirements. Dependency resolution is, however, an NP-hard problem, -and so the resolver uses a heuristic algorithm that may yield counterintuitive -results in some cases. The sections below provide some details on how +conflicting requirements. It turns out, however, that in many cases there is no +single "best" dependency resolution, and so the resolver must use heuristics to +choose a preferred solution. The sections below provide some details on how requirements are handled, and how to work with the resolver. See the chapter [Specifying Dependencies] for more details about how @@ -93,31 +93,6 @@ at the time of this writing) and Package B will use the greatest `0.6` release (`0.6.5` for example). This can lead to potential problems, see the [Version-incompatibility hazards] section for more details. -The resolver algorithm favors the greatest available versions of dependencies -and has limited support for backtracking in the solutions it attempts. -Therefore, it may converge on a solution that includes two copies of a -dependency when one would suffice. For example: - -```toml -# Package A -[dependencies] -rand = "0.7" - -# Package B -[dependencies] -rand = ">=0.6" -``` - -In this example, Cargo may build two copies of the rand crate: `0.8.5` (the -greatest available at the time of this writing) for Package B and `0.7.3` for -Package A — even though a single copy at version `0.7.3` meets all requirements. -Future revisions of the resolver algorithm may change this behavior. In the -meantime, the [`cargo update`] command with the `--precise` flag can be used to -manually remove such duplications. - -[`cargo update`]: ../commands/cargo-update.md - - Multiple versions within the same compatibility range are not allowed and will result in a resolver error if it is constrained to two different versions within a compatibility range. For example, if there are two packages in the @@ -517,6 +492,35 @@ break the build. The following illustrates some problems you may experience, and some possible solutions. +### Unexpected dependency duplication + +The resolver algorithm may converge on a solution that includes two copies of a +dependency when one would suffice. For example: + +```toml +# Package A +[dependencies] +rand = "0.7" + +# Package B +[dependencies] +rand = ">=0.6" # note: open requirements such as this are discouraged +``` + +In this example, Cargo may build two copies of the `rand` crate, even though a +single copy at version `0.7.3` would meet all requirements. This is because the +resolver's algorithm favors building the latest available version of `rand` for +Package B, which is `0.8.5` at the time of this writing, and that is +incompatible with Package A's specification. The resolver's algorithm does not +currently attempt to "deduplicate" in this situation. + +The use of open-ended version requirements like `>=0.6` is discouraged in Cargo. +But, if you run into this situation, the [`cargo update`] command with the +`--precise` flag can be used to manually remove such duplications. + +[`cargo update`]: ../commands/cargo-update.md + + ### SemVer-breaking patch release breaks the build Sometimes a project may inadvertently publish a point release with a