From 888077f64a63c8f6282614a66d6f8f0ce84a768c Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Thu, 19 Oct 2023 22:31:34 -0400 Subject: [PATCH] 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. --- src/cargo/core/resolver/mod.rs | 5 ++++- src/cargo/core/resolver/resolve.rs | 16 ++++++++++++++++ src/cargo/ops/lockfile.rs | 3 ++- tests/testsuite/lockfile_compat.rs | 12 ++++++------ 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/cargo/core/resolver/mod.rs b/src/cargo/core/resolver/mod.rs index 7d8e8acd4067..c102b78f30a7 100644 --- a/src/cargo/core/resolver/mod.rs +++ b/src/cargo/core/resolver/mod.rs @@ -150,6 +150,9 @@ pub fn resolve( Some(config) => config.cli_unstable().direct_minimal_versions, None => false, }; + + let resolve_version = ResolveVersion::with_rust_version(max_rust_version); + if !config .map(|c| c.cli_unstable().msrv_policy) .unwrap_or(false) @@ -203,7 +206,7 @@ pub fn resolve( cksums, BTreeMap::new(), Vec::new(), - ResolveVersion::default(), + resolve_version, summaries, ); diff --git a/src/cargo/core/resolver/resolve.rs b/src/cargo/core/resolver/resolve.rs index b401e923275e..dda0f5b92431 100644 --- a/src/cargo/core/resolver/resolve.rs +++ b/src/cargo/core/resolver/resolve.rs @@ -4,6 +4,7 @@ use crate::core::{Dependency, PackageId, PackageIdSpec, Summary, Target}; use crate::util::errors::CargoResult; use crate::util::interning::InternedString; use crate::util::Graph; +use crate::util::RustVersion; use std::borrow::Borrow; use std::collections::{HashMap, HashSet}; use std::fmt; @@ -97,6 +98,21 @@ impl ResolveVersion { pub fn max_stable() -> ResolveVersion { ResolveVersion::V3 } + + /// Gets the default lockfile version for the given Rust version. + pub fn with_rust_version(rust_version: Option<&RustVersion>) -> Self { + let Some(rust_version) = rust_version else { + return ResolveVersion::default(); + }; + + if rust_version >= &"1.53".parse::().unwrap() { + ResolveVersion::V3 + } else if rust_version >= &"1.41".parse::().unwrap() { + ResolveVersion::V2 + } else { + ResolveVersion::V1 + } + } } impl Resolve { diff --git a/src/cargo/ops/lockfile.rs b/src/cargo/ops/lockfile.rs index 2160b6f01541..f16a1f0d4a89 100644 --- a/src/cargo/ops/lockfile.rs +++ b/src/cargo/ops/lockfile.rs @@ -64,9 +64,10 @@ pub fn write_pkg_lockfile(ws: &Workspace<'_>, resolve: &mut Resolve) -> CargoRes // out lock file updates as they're otherwise already updated, and changes // which don't touch dependencies won't seemingly spuriously update the lock // file. - let default_version = ResolveVersion::default(); + let default_version = ResolveVersion::with_rust_version(ws.rust_version()); let current_version = resolve.version(); let next_lockfile_bump = ws.config().cli_unstable().next_lockfile_bump; + tracing::debug!("lockfile - current: {current_version:?}, default: {default_version:?}"); if current_version < default_version { resolve.set_version(default_version); diff --git a/tests/testsuite/lockfile_compat.rs b/tests/testsuite/lockfile_compat.rs index 74b3145d40f4..272c78e8762b 100644 --- a/tests/testsuite/lockfile_compat.rs +++ b/tests/testsuite/lockfile_compat.rs @@ -1220,23 +1220,23 @@ dependencies = [ let cases = [ // v1 is the default - ("1.37", None, 3), + ("1.37", None, 1), ("1.37", Some(1), 1), ("1.37", Some(2), 2), ("1.37", Some(3), 3), // v2 introduced - ("1.38", None, 3), + ("1.38", None, 1), // last version of v1 as the default - ("1.40", None, 3), + ("1.40", None, 1), // v2 is the default - ("1.41", None, 3), + ("1.41", None, 2), ("1.41", Some(1), 1), ("1.41", Some(2), 2), ("1.41", Some(3), 3), // v3 introduced - ("1.47", None, 3), + ("1.47", None, 2), // last version of v2 as the default - ("1.48", None, 3), + ("1.48", None, 2), // v3 is the default ("1.53", None, 3), ("1.53", Some(1), 1),