Skip to content

Commit d4b590a

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 04c956c commit d4b590a

File tree

6 files changed

+52
-8
lines changed

6 files changed

+52
-8
lines changed

crates/resolver-tests/src/lib.rs

+2
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

+4-1
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

+37
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};
@@ -99,6 +102,40 @@ impl ResolveVersion {
99102
pub fn max_stable() -> ResolveVersion {
100103
ResolveVersion::V4
101104
}
105+
106+
/// Gets the default lockfile version for the given Rust version.
107+
pub fn with_rust_version(rust_version: Option<&RustVersion>) -> Self {
108+
let Some(rust_version) = rust_version else {
109+
return ResolveVersion::default();
110+
};
111+
112+
let rust_1_41 = PartialVersion {
113+
major: 1,
114+
minor: Some(41),
115+
patch: None,
116+
pre: None,
117+
build: None,
118+
}
119+
.try_into()
120+
.expect("PartialVersion 1.41");
121+
let rust_1_53 = PartialVersion {
122+
major: 1,
123+
minor: Some(53),
124+
patch: None,
125+
pre: None,
126+
build: None,
127+
}
128+
.try_into()
129+
.expect("PartialVersion 1.53");
130+
131+
if rust_version >= &rust_1_53 {
132+
ResolveVersion::V3
133+
} else if rust_version >= &rust_1_41 {
134+
ResolveVersion::V2
135+
} else {
136+
ResolveVersion::V1
137+
}
138+
}
102139
}
103140

104141
impl Resolve {

src/cargo/ops/lockfile.rs

+2-1
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

+1
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

+6-6
Original file line numberDiff line numberDiff line change
@@ -1214,23 +1214,23 @@ dependencies = [
12141214

12151215
let cases = [
12161216
// v1 is the default
1217-
("1.37", None, 3),
1217+
("1.37", None, 1),
12181218
("1.37", Some(1), 1),
12191219
("1.37", Some(2), 2),
12201220
("1.37", Some(3), 3),
12211221
// v2 introduced
1222-
("1.38", None, 3),
1222+
("1.38", None, 1),
12231223
// last version of v1 as the default
1224-
("1.40", None, 3),
1224+
("1.40", None, 1),
12251225
// v2 is the default
1226-
("1.41", None, 3),
1226+
("1.41", None, 2),
12271227
("1.41", Some(1), 1),
12281228
("1.41", Some(2), 2),
12291229
("1.41", Some(3), 3),
12301230
// v3 introduced
1231-
("1.47", None, 3),
1231+
("1.47", None, 2),
12321232
// last version of v2 as the default
1233-
("1.48", None, 3),
1233+
("1.48", None, 2),
12341234
// v3 is the default
12351235
("1.53", None, 3),
12361236
("1.53", Some(1), 1),

0 commit comments

Comments
 (0)