You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Auto merge of #14639 - epage:stabilize-msrv-config, r=weihanglo
feat: Stabilize MSRV-aware resolver config
### What does this PR try to resolve?
This includes
- `cargo generate-lockfile --ignore-rust-version`
- `cargo update --ignore-rust-version`
This does not include
- `edition = "2024"`
- `resolver = "3"`
This is part of #9930
### How should we test and review this PR?
### Additional information
This is stacked on top of #14636. The commits for this PR start with the commit with a title that matches the PR title.
[FCP](#14639 (comment))
To support developing software with a minimum supported [Rust version],
209
+
the resolver can take into account a dependency version's compatibility with your Rust version.
210
+
This is controlled by the config field [`resolver.incompatible-rust-versions`].
211
+
212
+
With the `fallback` setting, the resolver will prefer packages with a Rust version that is
213
+
equal to or greater than your own Rust version.
214
+
For example, you are using Rust 1.85 to develop the following package:
215
+
```toml
216
+
[package]
217
+
name = "my-cli"
218
+
rust-version = "1.62"
219
+
220
+
[dependencies]
221
+
clap = "4.0"# resolves to 4.0.32
222
+
```
223
+
The resolver would pick version 4.0.32 because it has a Rust version of 1.60.0.
224
+
- 4.0.0 is not picked because it is a [lower version number](#version-numbers) despite it also having a Rust version of 1.60.0.
225
+
- 4.5.20 is not picked because it is incompatible with `my-cli`'s Rust version of 1.62 despite having a much [higher version](#version-numbers) and it has a Rust version of 1.74.0 which is compatible with your 1.85 toolchain.
226
+
227
+
If a version requirement does not include a Rust version compatible dependency version,
228
+
the resolver won't error but will instead pick a version, even if its potentially suboptimal.
229
+
For example, you change the dependency on `clap`:
230
+
```toml
231
+
[package]
232
+
name = "my-cli"
233
+
rust-version = "1.62"
234
+
235
+
[dependencies]
236
+
clap = "4.2"# resolves to 4.5.20
237
+
```
238
+
No version of `clap` matches that [version requirement](#version-requirements)
239
+
that is compatible with Rust version 1.62.
240
+
The resolver will then pick an incompatible version, like 4.5.20 despite it having a Rust version of 1.74.
241
+
242
+
When the resolver selects a dependency version of a package,
243
+
it does not know all the workspace members that will eventually have a transitive dependency on that version
244
+
and so it cannot take into account only the Rust versions relevant for that dependency.
245
+
The resolver has heuristics to find a "good enough" solution when workspace members have different Rust versions.
246
+
This applies even for packages in a workspace without a Rust version.
247
+
248
+
When a workspace has members with different Rust versions,
249
+
the resolver may pick a lower dependency version than necessary.
250
+
For example, you have the following workspace members:
251
+
```toml
252
+
[package]
253
+
name = "a"
254
+
rust-version = "1.62"
255
+
256
+
[package]
257
+
name = "b"
258
+
259
+
[dependencies]
260
+
clap = "4.2"# resolves to 4.5.20
261
+
```
262
+
Though package `b` does not have a Rust version and could use a higher version like 4.5.20,
263
+
4.0.32 will be selected because of package `a`'s Rust version of 1.62.
264
+
265
+
Or the resolver may pick too high of a version.
266
+
For example, you have the following workspace members:
267
+
```toml
268
+
[package]
269
+
name = "a"
270
+
rust-version = "1.62"
271
+
272
+
[dependencies]
273
+
clap = "4.2"# resolves to 4.5.20
274
+
275
+
[package]
276
+
name = "b"
277
+
278
+
[dependencies]
279
+
clap = "4.5"# resolves to 4.5.20
280
+
```
281
+
Though each package has a version requirement for `clap` that would meet its own Rust version,
282
+
because of [version unification](#version-numbers),
283
+
the resolver will need to pick one version that works in both cases and that would be a version like 4.5.20.
@@ -131,6 +133,10 @@ potentially limiting access to features of the shared dependency for the workspa
131
133
To allow users to patch a dependency on one of your workspace members,
132
134
every package in the workspace would need to be loadable in the oldest Rust version supported by the workspace.
133
135
136
+
When using [`incompatible-rust-versions = "fallback"`](config.md#resolverincompatible-rust-versions),
137
+
the Rust version of one package can affect dependency versions selected for another package with a different Rust version.
138
+
See the [resolver](resolver.md#rust-version) chapter for more details.
139
+
134
140
### One or More Policies
135
141
136
142
One way to mitigate the downsides of supporting older Rust versions is to apply your policy to older major or minor versions of your package that you continue to support.
Copy file name to clipboardexpand all lines: src/doc/src/reference/unstable.md
+1-25
Original file line number
Diff line number
Diff line change
@@ -351,31 +351,7 @@ This was stabilized in 1.79 in [#13608](https://github.com/rust-lang/cargo/pull/
351
351
352
352
### MSRV-aware resolver
353
353
354
-
`-Zmsrv-policy` allows access to an MSRV-aware resolver which can be enabled with:
355
-
-`resolver.incompatible-rust-versions` config field
-`package.edition = "2024"` (only in workspace root)
358
-
359
-
The resolver will prefer dependencies with a `package.rust-version` that is the same or older than your project's MSRV.
360
-
As the resolver is unable to determine which workspace members will eventually
361
-
depend on a package when it is being selected, we prioritize versions based on
362
-
how many workspace member MSRVs they are compatible with.
363
-
If there is no MSRV set then your toolchain version will be used, allowing it to pick up the toolchain version from pinned in rustup (e.g. `rust-toolchain.toml`).
When resolving a version for a dependency, select how versions with incompatible `package.rust-version`s are treated.
371
-
Values include:
372
-
-`allow`: treat `rust-version`-incompatible versions like any other version
373
-
-`fallback`: only consider `rust-version`-incompatible versions if no other version matched
374
-
375
-
Can be overridden with
376
-
-`--ignore-rust-version` CLI option
377
-
- Setting the dependency's version requirement higher than any version with a compatible `rust-version`
378
-
- Specifying the version to `cargo update` with `--precise`
354
+
This was stabilized in 1.83 in [#14639](https://github.com/rust-lang/cargo/pull/14639).
379
355
380
356
### Convert `incompatible_toolchain` error into a lint
0 commit comments