Skip to content

Commit 322fc94

Browse files
committed
docs(resolver): Split SemVer section into individual resolver pieces
We talked about three different roles of versions within the resolver in a way that made it easy to miss some of them.
1 parent 5a7118a commit 322fc94

File tree

1 file changed

+58
-44
lines changed

1 file changed

+58
-44
lines changed

src/doc/src/reference/resolver.md

+58-44
Original file line numberDiff line numberDiff line change
@@ -73,31 +73,48 @@ Key steps:
7373
falling back to the next version when backtracking.
7474
The resolver cannot backtrack because a more-preferred version becomes available.
7575

76+
### Version numbers
77+
78+
Cargo prefers the highest version currently available.
79+
80+
For example, if you had a package in the resolve graph with:
81+
```toml
82+
[dependencies]
83+
bitflags = "*"
84+
```
85+
If at the time the `Cargo.lock` file is generated, the greatest version of
86+
`bitflags` is `1.2.1`, then the package will use `1.2.1`.
87+
88+
### Version requirements
89+
90+
Package specify what versions they support, rejecting all others, through
91+
[version requirements].
92+
93+
For example, if you had a package in the resolve graph with:
94+
```toml
95+
[dependencies]
96+
bitflags = "1.0" # meaning `>=1.0.0,<2.0.0`
97+
```
98+
If at the time the `Cargo.lock` file is generated, the greatest version of
99+
`bitflags` is `1.2.1`, then the package will use `1.2.1` because it is the
100+
greatest within the compatibility range. If `2.0.0` is published, it will
101+
still use `1.2.1` because `2.0.0` is considered incompatible.
102+
103+
[version requirements]: specifying-dependencies.md#version-requirement-syntax
104+
76105
### SemVer compatibility
77106

78-
Cargo uses [SemVer] for specifying version numbers. This establishes a common
79-
convention for what is compatible between different versions of a package. See
80-
the [SemVer Compatibility] chapter for guidance on what is considered a
81-
"compatible" change. This notion of "compatibility" is important because Cargo
82-
assumes it should be safe to update a dependency within a compatibility range
83-
without breaking the build.
84-
85-
Versions are considered compatible if their left-most non-zero
86-
major/minor/patch component is the same. For example, `1.0.3` and `1.1.0` are
87-
considered compatible, and thus it should be safe to update from the older
88-
release to the newer one. However, an update from `1.1.0` to `2.0.0` would not
89-
be allowed to be made automatically. This convention also applies to versions
90-
with leading zeros. For example, `0.1.0` and `0.1.2` are compatible, but
91-
`0.1.0` and `0.2.0` are not. Similarly, `0.0.1` and `0.0.2` are not
92-
compatible.
93-
94-
When multiple packages specify a dependency for a common package, the resolver
95-
attempts to ensure that they use the same version of that common package, as
96-
long as they are within a SemVer compatibility range. It also attempts to use
97-
the greatest version currently available within that compatibility range. For
98-
example, if there are two packages in the resolve graph with the following
99-
requirements:
107+
Cargo assumes packages follow [SemVer] and will unify dependency versions if they are
108+
[SemVer] compatible according to the [Caret version requirements].
109+
If two compatible versions cannot be unified because of conflicting version requirements,
110+
Cargo will error.
111+
112+
See the [SemVer Compatibility] chapter for guidance on what is considered a
113+
"compatible" change.
100114

115+
Examples:
116+
117+
The following two packages will have their dependencies on `bitflags` unified because any version picked will be compatible with each other.
101118
```toml
102119
# Package A
103120
[dependencies]
@@ -108,15 +125,20 @@ bitflags = "1.0" # meaning `>=1.0.0,<2.0.0`
108125
bitflags = "1.1" # meaning `>=1.1.0,<2.0.0`
109126
```
110127

111-
If at the time the `Cargo.lock` file is generated, the greatest version of
112-
`bitflags` is `1.2.1`, then both packages will use `1.2.1` because it is the
113-
greatest within the compatibility range. If `2.0.0` is published, it will
114-
still use `1.2.1` because `2.0.0` is considered incompatible.
128+
The following packages will error because the version requirements conflict, selecting two distinct compatible versions.
129+
```toml
130+
# Package A
131+
[dependencies]
132+
log = "=0.4.11"
115133

116-
If multiple packages have a common dependency with semver-incompatible
117-
versions, then Cargo will allow this, but will build two separate copies of
118-
the dependency. For example:
134+
# Package B
135+
[dependencies]
136+
log = "=0.4.8"
137+
```
119138

139+
The following two packages will not have their dependencies on `rand` unified because only incompatible versions are available for each.
140+
Instead, two different versions (e.g. 0.6.5 and 0.7.3) will be resolved and built.
141+
This can lead to potential problems, see the [Version-incompatibility hazards] section for more details.
120142
```toml
121143
# Package A
122144
[dependencies]
@@ -127,31 +149,23 @@ rand = "0.7" # meaning `>=0.7.0,<0.8.0`
127149
rand = "0.6" # meaning `>=0.6.0,<0.7.0`
128150
```
129151

130-
The above will result in Package A using the greatest `0.7` release (`0.7.3`
131-
at the time of this writing) and Package B will use the greatest `0.6` release
132-
(`0.6.5` for example). This can lead to potential problems, see the
133-
[Version-incompatibility hazards] section for more details.
134-
135-
Multiple versions within the same compatibility range are not allowed and will
136-
result in a resolver error if it is constrained to two different versions
137-
within a compatibility range. For example, if there are two packages in the
138-
resolve graph with the following requirements:
139-
152+
Generally, the following two packages will not have their dependencies unified because incompatible versions are available that satisfy the version requirements:
153+
Instead, two different versions (e.g. 0.6.5 and 0.7.3) will be resolved and built.
154+
The application of other constraints or heuristics may cause these to be unified,
155+
picking one version (e.g. 0.6.5).
140156
```toml
141157
# Package A
142158
[dependencies]
143-
log = "=0.4.11"
159+
rand = ">=0.6,<0.8.0"
144160

145161
# Package B
146162
[dependencies]
147-
log = "=0.4.8"
163+
rand = "0.6" # meaning `>=0.6.0,<0.7.0`
148164
```
149165

150-
The above will fail because it is not allowed to have two separate copies of
151-
the `0.4` release of the `log` package.
152-
153166
[SemVer]: https://semver.org/
154167
[SemVer Compatibility]: semver.md
168+
[Caret version requirements]: specifying-dependencies.md#default-requirements
155169
[Version-incompatibility hazards]: #version-incompatibility-hazards
156170

157171
#### Version-incompatibility hazards

0 commit comments

Comments
 (0)