mirror of https://github.com/rust-lang/cargo
feat(resolver): Respect MSRV
This commit is contained in:
parent
10196aaee3
commit
4820624ce7
|
@ -31,6 +31,7 @@ fn do_resolve<'cfg>(config: &'cfg Config, ws_root: &Path) -> ResolveInfo<'cfg> {
|
|||
let specs = pkgs.to_package_id_specs(&ws).unwrap();
|
||||
let has_dev_units = HasDevUnits::Yes;
|
||||
let force_all_targets = ForceAllTargets::No;
|
||||
let max_rust_version = None;
|
||||
// Do an initial run to download anything necessary so that it does
|
||||
// not confuse criterion's warmup.
|
||||
let ws_resolve = cargo::ops::resolve_ws_with_opts(
|
||||
|
@ -41,6 +42,7 @@ fn do_resolve<'cfg>(config: &'cfg Config, ws_root: &Path) -> ResolveInfo<'cfg> {
|
|||
&specs,
|
||||
has_dev_units,
|
||||
force_all_targets,
|
||||
max_rust_version,
|
||||
)
|
||||
.unwrap();
|
||||
ResolveInfo {
|
||||
|
@ -82,6 +84,7 @@ fn resolve_ws(c: &mut Criterion) {
|
|||
force_all_targets,
|
||||
..
|
||||
} = lazy_info.get_or_insert_with(|| do_resolve(&config, &ws_root));
|
||||
let max_rust_version = None;
|
||||
b.iter(|| {
|
||||
cargo::ops::resolve_ws_with_opts(
|
||||
ws,
|
||||
|
@ -91,6 +94,7 @@ fn resolve_ws(c: &mut Criterion) {
|
|||
specs,
|
||||
*has_dev_units,
|
||||
*force_all_targets,
|
||||
max_rust_version,
|
||||
)
|
||||
.unwrap();
|
||||
})
|
||||
|
|
|
@ -188,6 +188,7 @@ pub fn resolve_with_config_raw(
|
|||
.unwrap();
|
||||
let opts = ResolveOpts::everything();
|
||||
let start = Instant::now();
|
||||
let max_rust_version = None;
|
||||
let resolve = resolver::resolve(
|
||||
&[(summary, opts)],
|
||||
&[],
|
||||
|
@ -195,6 +196,7 @@ pub fn resolve_with_config_raw(
|
|||
&VersionPreferences::default(),
|
||||
Some(config),
|
||||
true,
|
||||
max_rust_version,
|
||||
);
|
||||
|
||||
// The largest test in our suite takes less then 30 sec.
|
||||
|
|
|
@ -145,6 +145,7 @@ pub fn resolve_std<'cfg>(
|
|||
let cli_features = CliFeatures::from_command_line(
|
||||
&features, /*all_features*/ false, /*uses_default_features*/ false,
|
||||
)?;
|
||||
let max_rust_version = ws.rust_version();
|
||||
let resolve = ops::resolve_ws_with_opts(
|
||||
&std_ws,
|
||||
target_data,
|
||||
|
@ -153,6 +154,7 @@ pub fn resolve_std<'cfg>(
|
|||
&specs,
|
||||
HasDevUnits::No,
|
||||
crate::core::resolver::features::ForceAllTargets::No,
|
||||
max_rust_version,
|
||||
)?;
|
||||
Ok((
|
||||
resolve.pkg_set,
|
||||
|
|
|
@ -21,6 +21,7 @@ use crate::core::{
|
|||
};
|
||||
use crate::util::errors::CargoResult;
|
||||
use crate::util::interning::InternedString;
|
||||
use crate::util::PartialVersion;
|
||||
|
||||
use anyhow::Context as _;
|
||||
use std::collections::{BTreeSet, HashMap, HashSet};
|
||||
|
@ -36,6 +37,7 @@ pub struct RegistryQueryer<'a> {
|
|||
/// versions first. That allows `cargo update -Z minimal-versions` which will
|
||||
/// specify minimum dependency versions to be used.
|
||||
minimal_versions: bool,
|
||||
max_rust_version: Option<PartialVersion>,
|
||||
/// a cache of `Candidate`s that fulfil a `Dependency` (and whether `first_minimal_version`)
|
||||
registry_cache: HashMap<(Dependency, bool), Poll<Rc<Vec<Summary>>>>,
|
||||
/// a cache of `Dependency`s that are required for a `Summary`
|
||||
|
@ -57,12 +59,14 @@ impl<'a> RegistryQueryer<'a> {
|
|||
replacements: &'a [(PackageIdSpec, Dependency)],
|
||||
version_prefs: &'a VersionPreferences,
|
||||
minimal_versions: bool,
|
||||
max_rust_version: Option<PartialVersion>,
|
||||
) -> Self {
|
||||
RegistryQueryer {
|
||||
registry,
|
||||
replacements,
|
||||
version_prefs,
|
||||
minimal_versions,
|
||||
max_rust_version,
|
||||
registry_cache: HashMap::new(),
|
||||
summary_cache: HashMap::new(),
|
||||
used_replacements: HashMap::new(),
|
||||
|
@ -112,7 +116,9 @@ impl<'a> RegistryQueryer<'a> {
|
|||
|
||||
let mut ret = Vec::new();
|
||||
let ready = self.registry.query(dep, QueryKind::Exact, &mut |s| {
|
||||
ret.push(s);
|
||||
if self.max_rust_version.is_none() || s.rust_version() <= self.max_rust_version {
|
||||
ret.push(s);
|
||||
}
|
||||
})?;
|
||||
if ready.is_pending() {
|
||||
self.registry_cache
|
||||
|
|
|
@ -71,6 +71,7 @@ use crate::util::config::Config;
|
|||
use crate::util::errors::CargoResult;
|
||||
use crate::util::network::PollExt;
|
||||
use crate::util::profile;
|
||||
use crate::util::PartialVersion;
|
||||
|
||||
use self::context::Context;
|
||||
use self::dep_cache::RegistryQueryer;
|
||||
|
@ -138,6 +139,7 @@ pub fn resolve(
|
|||
version_prefs: &VersionPreferences,
|
||||
config: Option<&Config>,
|
||||
check_public_visible_dependencies: bool,
|
||||
mut max_rust_version: Option<PartialVersion>,
|
||||
) -> CargoResult<Resolve> {
|
||||
let _p = profile::start("resolving");
|
||||
let minimal_versions = match config {
|
||||
|
@ -148,8 +150,19 @@ pub fn resolve(
|
|||
Some(config) => config.cli_unstable().direct_minimal_versions,
|
||||
None => false,
|
||||
};
|
||||
let mut registry =
|
||||
RegistryQueryer::new(registry, replacements, version_prefs, minimal_versions);
|
||||
if !config
|
||||
.map(|c| c.cli_unstable().msrv_policy)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
max_rust_version = None;
|
||||
}
|
||||
let mut registry = RegistryQueryer::new(
|
||||
registry,
|
||||
replacements,
|
||||
version_prefs,
|
||||
minimal_versions,
|
||||
max_rust_version,
|
||||
);
|
||||
let cx = loop {
|
||||
let cx = Context::new(check_public_visible_dependencies);
|
||||
let cx = activate_deps_loop(
|
||||
|
|
|
@ -23,6 +23,7 @@ use crate::util::edit_distance;
|
|||
use crate::util::errors::{CargoResult, ManifestError};
|
||||
use crate::util::interning::InternedString;
|
||||
use crate::util::toml::{read_manifest, InheritableFields, TomlDependency, TomlProfiles};
|
||||
use crate::util::PartialVersion;
|
||||
use crate::util::{config::ConfigRelativePath, Config, Filesystem, IntoUrl};
|
||||
use cargo_util::paths;
|
||||
use cargo_util::paths::normalize_path;
|
||||
|
@ -595,6 +596,12 @@ impl<'cfg> Workspace<'cfg> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Get the lowest-common denominator `package.rust-version` within the workspace, if specified
|
||||
/// anywhere
|
||||
pub fn rust_version(&self) -> Option<PartialVersion> {
|
||||
self.members().filter_map(|pkg| pkg.rust_version()).min()
|
||||
}
|
||||
|
||||
pub fn custom_metadata(&self) -> Option<&toml::Value> {
|
||||
self.custom_metadata.as_ref()
|
||||
}
|
||||
|
|
|
@ -261,6 +261,7 @@ pub fn create_bcx<'a, 'cfg>(
|
|||
HasDevUnits::No
|
||||
}
|
||||
};
|
||||
let max_rust_version = ws.rust_version();
|
||||
let resolve = ops::resolve_ws_with_opts(
|
||||
ws,
|
||||
&mut target_data,
|
||||
|
@ -269,6 +270,7 @@ pub fn create_bcx<'a, 'cfg>(
|
|||
&specs,
|
||||
has_dev_units,
|
||||
crate::core::resolver::features::ForceAllTargets::No,
|
||||
max_rust_version,
|
||||
)?;
|
||||
let WorkspaceResolve {
|
||||
mut pkg_set,
|
||||
|
|
|
@ -21,6 +21,7 @@ pub struct UpdateOptions<'a> {
|
|||
|
||||
pub fn generate_lockfile(ws: &Workspace<'_>) -> CargoResult<()> {
|
||||
let mut registry = PackageRegistry::new(ws.config())?;
|
||||
let max_rust_version = ws.rust_version();
|
||||
let mut resolve = ops::resolve_with_previous(
|
||||
&mut registry,
|
||||
ws,
|
||||
|
@ -30,6 +31,7 @@ pub fn generate_lockfile(ws: &Workspace<'_>) -> CargoResult<()> {
|
|||
None,
|
||||
&[],
|
||||
true,
|
||||
max_rust_version,
|
||||
)?;
|
||||
ops::write_pkg_lockfile(ws, &mut resolve)?;
|
||||
Ok(())
|
||||
|
@ -48,6 +50,8 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
|
|||
// that we're synchronized against other Cargos.
|
||||
let _lock = ws.config().acquire_package_cache_lock()?;
|
||||
|
||||
let max_rust_version = ws.rust_version();
|
||||
|
||||
let previous_resolve = match ops::load_pkg_lockfile(ws)? {
|
||||
Some(resolve) => resolve,
|
||||
None => {
|
||||
|
@ -67,6 +71,7 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
|
|||
None,
|
||||
&[],
|
||||
true,
|
||||
max_rust_version,
|
||||
)?
|
||||
}
|
||||
}
|
||||
|
@ -125,6 +130,7 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
|
|||
Some(&to_avoid),
|
||||
&[],
|
||||
true,
|
||||
max_rust_version,
|
||||
)?;
|
||||
|
||||
// Summarize what is changing for the user.
|
||||
|
|
|
@ -135,6 +135,8 @@ fn build_resolve_graph(
|
|||
crate::core::resolver::features::ForceAllTargets::No
|
||||
};
|
||||
|
||||
let max_rust_version = ws.rust_version();
|
||||
|
||||
// Note that even with --filter-platform we end up downloading host dependencies as well,
|
||||
// as that is the behavior of download_accessible.
|
||||
let ws_resolve = ops::resolve_ws_with_opts(
|
||||
|
@ -145,6 +147,7 @@ fn build_resolve_graph(
|
|||
&specs,
|
||||
HasDevUnits::Yes,
|
||||
force_all,
|
||||
max_rust_version,
|
||||
)?;
|
||||
|
||||
let package_map: BTreeMap<PackageId, Package> = ws_resolve
|
||||
|
|
|
@ -423,6 +423,8 @@ fn build_lock(ws: &Workspace<'_>, orig_pkg: &Package) -> CargoResult<String> {
|
|||
TomlManifest::to_real_manifest(&toml_manifest, false, source_id, package_root, config)?;
|
||||
let new_pkg = Package::new(manifest, orig_pkg.manifest_path());
|
||||
|
||||
let max_rust_version = new_pkg.rust_version();
|
||||
|
||||
// Regenerate Cargo.lock using the old one as a guide.
|
||||
let tmp_ws = Workspace::ephemeral(new_pkg, ws.config(), None, true)?;
|
||||
let mut tmp_reg = PackageRegistry::new(ws.config())?;
|
||||
|
@ -435,6 +437,7 @@ fn build_lock(ws: &Workspace<'_>, orig_pkg: &Package) -> CargoResult<String> {
|
|||
None,
|
||||
&[],
|
||||
true,
|
||||
max_rust_version,
|
||||
)?;
|
||||
let pkg_set = ops::get_resolved_packages(&new_resolve, tmp_reg)?;
|
||||
|
||||
|
|
|
@ -246,6 +246,8 @@ fn check_resolver_change(ws: &Workspace<'_>, opts: &FixOptions) -> CargoResult<(
|
|||
let mut target_data =
|
||||
RustcTargetData::new(ws, &opts.compile_opts.build_config.requested_kinds)?;
|
||||
let mut resolve_differences = |has_dev_units| -> CargoResult<(WorkspaceResolve<'_>, DiffMap)> {
|
||||
let max_rust_version = ws.rust_version();
|
||||
|
||||
let ws_resolve = ops::resolve_ws_with_opts(
|
||||
ws,
|
||||
&mut target_data,
|
||||
|
@ -254,6 +256,7 @@ fn check_resolver_change(ws: &Workspace<'_>, opts: &FixOptions) -> CargoResult<(
|
|||
&specs,
|
||||
has_dev_units,
|
||||
crate::core::resolver::features::ForceAllTargets::No,
|
||||
max_rust_version,
|
||||
)?;
|
||||
|
||||
let feature_opts = FeatureOpts::new_behavior(ResolveBehavior::V2, has_dev_units);
|
||||
|
|
|
@ -69,6 +69,7 @@ use crate::core::{GitReference, PackageId, PackageIdSpec, PackageSet, SourceId,
|
|||
use crate::ops;
|
||||
use crate::sources::PathSource;
|
||||
use crate::util::errors::CargoResult;
|
||||
use crate::util::PartialVersion;
|
||||
use crate::util::{profile, CanonicalUrl};
|
||||
use anyhow::Context as _;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
@ -106,8 +107,10 @@ version. This may also occur with an optional dependency that is not enabled.";
|
|||
/// This is a simple interface used by commands like `clean`, `fetch`, and
|
||||
/// `package`, which don't specify any options or features.
|
||||
pub fn resolve_ws<'a>(ws: &Workspace<'a>) -> CargoResult<(PackageSet<'a>, Resolve)> {
|
||||
let max_rust_version = ws.rust_version();
|
||||
|
||||
let mut registry = PackageRegistry::new(ws.config())?;
|
||||
let resolve = resolve_with_registry(ws, &mut registry)?;
|
||||
let resolve = resolve_with_registry(ws, &mut registry, max_rust_version)?;
|
||||
let packages = get_resolved_packages(&resolve, registry)?;
|
||||
Ok((packages, resolve))
|
||||
}
|
||||
|
@ -130,6 +133,7 @@ pub fn resolve_ws_with_opts<'cfg>(
|
|||
specs: &[PackageIdSpec],
|
||||
has_dev_units: HasDevUnits,
|
||||
force_all_targets: ForceAllTargets,
|
||||
max_rust_version: Option<PartialVersion>,
|
||||
) -> CargoResult<WorkspaceResolve<'cfg>> {
|
||||
let mut registry = PackageRegistry::new(ws.config())?;
|
||||
let mut add_patches = true;
|
||||
|
@ -138,7 +142,7 @@ pub fn resolve_ws_with_opts<'cfg>(
|
|||
} else if ws.require_optional_deps() {
|
||||
// First, resolve the root_package's *listed* dependencies, as well as
|
||||
// downloading and updating all remotes and such.
|
||||
let resolve = resolve_with_registry(ws, &mut registry)?;
|
||||
let resolve = resolve_with_registry(ws, &mut registry, max_rust_version)?;
|
||||
// No need to add patches again, `resolve_with_registry` has done it.
|
||||
add_patches = false;
|
||||
|
||||
|
@ -184,6 +188,7 @@ pub fn resolve_ws_with_opts<'cfg>(
|
|||
None,
|
||||
specs,
|
||||
add_patches,
|
||||
max_rust_version,
|
||||
)?;
|
||||
|
||||
let pkg_set = get_resolved_packages(&resolved_with_overrides, registry)?;
|
||||
|
@ -235,6 +240,7 @@ pub fn resolve_ws_with_opts<'cfg>(
|
|||
fn resolve_with_registry<'cfg>(
|
||||
ws: &Workspace<'cfg>,
|
||||
registry: &mut PackageRegistry<'cfg>,
|
||||
max_rust_version: Option<PartialVersion>,
|
||||
) -> CargoResult<Resolve> {
|
||||
let prev = ops::load_pkg_lockfile(ws)?;
|
||||
let mut resolve = resolve_with_previous(
|
||||
|
@ -246,6 +252,7 @@ fn resolve_with_registry<'cfg>(
|
|||
None,
|
||||
&[],
|
||||
true,
|
||||
max_rust_version,
|
||||
)?;
|
||||
|
||||
if !ws.is_ephemeral() && ws.require_optional_deps() {
|
||||
|
@ -278,6 +285,7 @@ pub fn resolve_with_previous<'cfg>(
|
|||
to_avoid: Option<&HashSet<PackageId>>,
|
||||
specs: &[PackageIdSpec],
|
||||
register_patches: bool,
|
||||
max_rust_version: Option<PartialVersion>,
|
||||
) -> CargoResult<Resolve> {
|
||||
// We only want one Cargo at a time resolving a crate graph since this can
|
||||
// involve a lot of frobbing of the global caches.
|
||||
|
@ -505,6 +513,7 @@ pub fn resolve_with_previous<'cfg>(
|
|||
ws.unstable_features()
|
||||
.require(Feature::public_dependency())
|
||||
.is_ok(),
|
||||
max_rust_version,
|
||||
)?;
|
||||
let patches: Vec<_> = registry
|
||||
.patches()
|
||||
|
|
|
@ -150,6 +150,7 @@ pub fn build_and_print(ws: &Workspace<'_>, opts: &TreeOptions) -> CargoResult<()
|
|||
} else {
|
||||
ForceAllTargets::No
|
||||
};
|
||||
let max_rust_version = ws.rust_version();
|
||||
let ws_resolve = ops::resolve_ws_with_opts(
|
||||
ws,
|
||||
&mut target_data,
|
||||
|
@ -158,6 +159,7 @@ pub fn build_and_print(ws: &Workspace<'_>, opts: &TreeOptions) -> CargoResult<()
|
|||
&specs,
|
||||
has_dev,
|
||||
force_all,
|
||||
max_rust_version,
|
||||
)?;
|
||||
|
||||
let package_map: HashMap<PackageId, &Package> = ws_resolve
|
||||
|
|
|
@ -108,7 +108,7 @@ impl From<VersionReq> for OptVersionReq {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone, Debug)]
|
||||
pub struct PartialVersion {
|
||||
pub major: u64,
|
||||
pub minor: Option<u64>,
|
||||
|
|
|
@ -26,7 +26,7 @@ fn case() {
|
|||
.current_dir(cwd)
|
||||
.masquerade_as_nightly_cargo(&["msrv-policy"])
|
||||
.assert()
|
||||
.success()
|
||||
.code(101)
|
||||
.stdout_matches_path(curr_dir!().join("stdout.log"))
|
||||
.stderr_matches_path(curr_dir!().join("stderr.log"));
|
||||
|
||||
|
|
|
@ -1,2 +1,7 @@
|
|||
Updating `dummy-registry` index
|
||||
Adding rust-version-user v0.2.1 to dependencies.
|
||||
error: failed to select a version for the requirement `rust-version-user = "^0.2.1"`
|
||||
candidate versions found which didn't match: 0.2.1, 0.1.0
|
||||
location searched: `dummy-registry` index (which is replacing registry `crates-io`)
|
||||
required by package `cargo-list-test-fixture v0.0.0 ([ROOT]/case)`
|
||||
perhaps a crate was updated and forgotten to be re-vendored?
|
||||
|
|
Loading…
Reference in New Issue