Skip to content

Commit 0d072e1

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 16dbce1 commit 0d072e1

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
@@ -71,31 +71,48 @@ Key steps:
7171
Cargo may decide that it should prefer a specific version,
7272
falling back to the next version when backtracking.
7373

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

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

113+
Examples:
114+
115+
The following two packages will have their dependencies on `bitflags` unified because any version picked will be compatible with each other.
99116
```toml
100117
# Package A
101118
[dependencies]
@@ -106,15 +123,20 @@ bitflags = "1.0" # meaning `>=1.0.0,<2.0.0`
106123
bitflags = "1.1" # meaning `>=1.1.0,<2.0.0`
107124
```
108125

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

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

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

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

143159
# Package B
144160
[dependencies]
145-
log = "=0.4.8"
161+
rand = "0.6" # meaning `>=0.6.0,<0.7.0`
146162
```
147163

148-
The above will fail because it is not allowed to have two separate copies of
149-
the `0.4` release of the `log` package.
150-
151164
[SemVer]: https://semver.org/
152165
[SemVer Compatibility]: semver.md
166+
[Caret version requirements]: specifying-dependencies.md#default-requirements
153167
[Version-incompatibility hazards]: #version-incompatibility-hazards
154168

155169
#### Version-incompatibility hazards

0 commit comments

Comments
 (0)