Skip to content

Commit db1b1f9

Browse files
committed
feat: respect rust-version when generating lockfile
MSRV-aware resolver has been implemented in PR 12560. Based on that effort, generating lockfile can now respect `rust-version` so that a package with an old MSRV will never get an incompatible lockfile, even using the latest Cargo.
1 parent c4e5d33 commit db1b1f9

File tree

6 files changed

+52
-8
lines changed

6 files changed

+52
-8
lines changed

crates/resolver-tests/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use std::time::Instant;
1414
use cargo::core::dependency::DepKind;
1515
use cargo::core::resolver::{self, ResolveOpts, VersionOrdering, VersionPreferences};
1616
use cargo::core::Resolve;
17+
use cargo::core::ResolveVersion;
1718
use cargo::core::{Dependency, PackageId, Registry, Summary};
1819
use cargo::core::{GitReference, SourceId};
1920
use cargo::sources::source::QueryKind;
@@ -174,6 +175,7 @@ pub fn resolve_with_config_raw(
174175
&[],
175176
&mut registry,
176177
&version_prefs,
178+
ResolveVersion::default(),
177179
Some(config),
178180
);
179181

src/cargo/core/resolver/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,16 @@ mod version_prefs;
118118
/// * `version_prefs` - this represents a preference for some versions over others,
119119
/// based on the lock file or other reasons such as `[patch]`es.
120120
///
121+
/// * `resolve_version` - this controls how the lockfile will be serialized.
122+
///
121123
/// * `config` - a location to print warnings and such, or `None` if no warnings
122124
/// should be printed
123125
pub fn resolve(
124126
summaries: &[(Summary, ResolveOpts)],
125127
replacements: &[(PackageIdSpec, Dependency)],
126128
registry: &mut dyn Registry,
127129
version_prefs: &VersionPreferences,
130+
resolve_version: ResolveVersion,
128131
config: Option<&Config>,
129132
) -> CargoResult<Resolve> {
130133
let _p = profile::start("resolving");
@@ -169,7 +172,7 @@ pub fn resolve(
169172
cksums,
170173
BTreeMap::new(),
171174
Vec::new(),
172-
ResolveVersion::default(),
175+
resolve_version,
173176
summaries,
174177
);
175178

src/cargo/core/resolver/resolve.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use cargo_util_schemas::core::PartialVersion;
2+
use cargo_util_schemas::manifest::RustVersion;
3+
14
use super::encode::Metadata;
25
use crate::core::dependency::DepKind;
36
use crate::core::{Dependency, PackageId, PackageIdSpec, PackageIdSpecQuery, Summary, Target};
@@ -97,6 +100,40 @@ impl ResolveVersion {
97100
pub fn max_stable() -> ResolveVersion {
98101
ResolveVersion::V3
99102
}
103+
104+
/// Gets the default lockfile version for the given Rust version.
105+
pub fn with_rust_version(rust_version: Option<&RustVersion>) -> Self {
106+
let Some(rust_version) = rust_version else {
107+
return ResolveVersion::default();
108+
};
109+
110+
let rust_1_41 = PartialVersion {
111+
major: 1,
112+
minor: Some(41),
113+
patch: None,
114+
pre: None,
115+
build: None,
116+
}
117+
.try_into()
118+
.expect("PartialVersion 1.41");
119+
let rust_1_53 = PartialVersion {
120+
major: 1,
121+
minor: Some(53),
122+
patch: None,
123+
pre: None,
124+
build: None,
125+
}
126+
.try_into()
127+
.expect("PartialVersion 1.53");
128+
129+
if rust_version >= &rust_1_53 {
130+
ResolveVersion::V3
131+
} else if rust_version >= &rust_1_41 {
132+
ResolveVersion::V2
133+
} else {
134+
ResolveVersion::V1
135+
}
136+
}
100137
}
101138

102139
impl Resolve {

src/cargo/ops/lockfile.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,10 @@ pub fn write_pkg_lockfile(ws: &Workspace<'_>, resolve: &mut Resolve) -> CargoRes
6464
// out lock file updates as they're otherwise already updated, and changes
6565
// which don't touch dependencies won't seemingly spuriously update the lock
6666
// file.
67-
let default_version = ResolveVersion::default();
67+
let default_version = ResolveVersion::with_rust_version(ws.rust_version());
6868
let current_version = resolve.version();
6969
let next_lockfile_bump = ws.config().cli_unstable().next_lockfile_bump;
70+
tracing::debug!("lockfile - current: {current_version:?}, default: {default_version:?}");
7071

7172
if current_version < default_version {
7273
resolve.set_version(default_version);

src/cargo/ops/resolve.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,7 @@ pub fn resolve_with_previous<'cfg>(
504504
&replace,
505505
registry,
506506
&version_prefs,
507+
ResolveVersion::with_rust_version(ws.rust_version()),
507508
Some(ws.config()),
508509
)?;
509510
let patches: Vec<_> = registry

tests/testsuite/lockfile_compat.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,23 +1220,23 @@ dependencies = [
12201220

12211221
let cases = [
12221222
// v1 is the default
1223-
("1.37", None, 3),
1223+
("1.37", None, 1),
12241224
("1.37", Some(1), 1),
12251225
("1.37", Some(2), 2),
12261226
("1.37", Some(3), 3),
12271227
// v2 introduced
1228-
("1.38", None, 3),
1228+
("1.38", None, 1),
12291229
// last version of v1 as the default
1230-
("1.40", None, 3),
1230+
("1.40", None, 1),
12311231
// v2 is the default
1232-
("1.41", None, 3),
1232+
("1.41", None, 2),
12331233
("1.41", Some(1), 1),
12341234
("1.41", Some(2), 2),
12351235
("1.41", Some(3), 3),
12361236
// v3 introduced
1237-
("1.47", None, 3),
1237+
("1.47", None, 2),
12381238
// last version of v2 as the default
1239-
("1.48", None, 3),
1239+
("1.48", None, 2),
12401240
// v3 is the default
12411241
("1.53", None, 3),
12421242
("1.53", Some(1), 1),

0 commit comments

Comments
 (0)