diff --git a/crates/resolver-tests/src/lib.rs b/crates/resolver-tests/src/lib.rs index eae6469545d..fd190fe6b3b 100644 --- a/crates/resolver-tests/src/lib.rs +++ b/crates/resolver-tests/src/lib.rs @@ -12,7 +12,7 @@ use std::time::Instant; use cargo::core::dependency::DepKind; use cargo::core::resolver::{self, ResolveOpts, VersionPreferences}; -use cargo::core::source::{GitReference, SourceId}; +use cargo::core::source::{GitReference, QueryKind, SourceId}; use cargo::core::Resolve; use cargo::core::{Dependency, PackageId, Registry, Summary}; use cargo::util::{CargoResult, Config, Graph, IntoUrl}; @@ -128,11 +128,15 @@ pub fn resolve_with_config_raw( fn query( &mut self, dep: &Dependency, + kind: QueryKind, f: &mut dyn FnMut(Summary), - fuzzy: bool, ) -> Poll> { for summary in self.list.iter() { - if fuzzy || dep.matches(summary) { + let matched = match kind { + QueryKind::Exact => dep.matches(summary), + QueryKind::Fuzzy => true, + }; + if matched { self.used.insert(summary.package_id()); f(summary.clone()); } diff --git a/src/cargo/core/compiler/future_incompat.rs b/src/cargo/core/compiler/future_incompat.rs index c814842dff7..61b2c47fd87 100644 --- a/src/cargo/core/compiler/future_incompat.rs +++ b/src/cargo/core/compiler/future_incompat.rs @@ -1,7 +1,7 @@ //! Support for future-incompatible warning reporting. use crate::core::compiler::BuildContext; -use crate::core::{Dependency, PackageId, Workspace}; +use crate::core::{Dependency, PackageId, QueryKind, Workspace}; use crate::sources::SourceConfigMap; use crate::util::{iter_join, CargoResult, Config}; use anyhow::{bail, format_err, Context}; @@ -293,7 +293,7 @@ fn get_updates(ws: &Workspace<'_>, package_ids: &BTreeSet) -> Option< Ok(dep) => dep, Err(_) => return false, }; - match source.query_vec(&dep) { + match source.query_vec(&dep, QueryKind::Exact) { Poll::Ready(Ok(sum)) => { summaries.push((pkg_id, sum)); false diff --git a/src/cargo/core/mod.rs b/src/cargo/core/mod.rs index df91808ccaf..e36c678c4cb 100644 --- a/src/cargo/core/mod.rs +++ b/src/cargo/core/mod.rs @@ -8,7 +8,7 @@ pub use self::package_id_spec::PackageIdSpec; pub use self::registry::Registry; pub use self::resolver::{Resolve, ResolveVersion}; pub use self::shell::{Shell, Verbosity}; -pub use self::source::{GitReference, Source, SourceId, SourceMap}; +pub use self::source::{GitReference, QueryKind, Source, SourceId, SourceMap}; pub use self::summary::{FeatureMap, FeatureValue, Summary}; pub use self::workspace::{ find_workspace_root, resolve_relative_path, MaybePackage, Workspace, WorkspaceConfig, diff --git a/src/cargo/core/registry.rs b/src/cargo/core/registry.rs index 9e9d1408432..0d788a05c43 100644 --- a/src/cargo/core/registry.rs +++ b/src/cargo/core/registry.rs @@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet}; use std::task::Poll; use crate::core::PackageSet; -use crate::core::{Dependency, PackageId, Source, SourceId, SourceMap, Summary}; +use crate::core::{Dependency, PackageId, QueryKind, Source, SourceId, SourceMap, Summary}; use crate::sources::config::SourceConfigMap; use crate::util::errors::CargoResult; use crate::util::interning::InternedString; @@ -19,14 +19,13 @@ pub trait Registry { fn query( &mut self, dep: &Dependency, + kind: QueryKind, f: &mut dyn FnMut(Summary), - fuzzy: bool, ) -> Poll>; - fn query_vec(&mut self, dep: &Dependency, fuzzy: bool) -> Poll>> { + fn query_vec(&mut self, dep: &Dependency, kind: QueryKind) -> Poll>> { let mut ret = Vec::new(); - self.query(dep, &mut |s| ret.push(s), fuzzy) - .map_ok(|()| ret) + self.query(dep, kind, &mut |s| ret.push(s)).map_ok(|()| ret) } fn describe_source(&self, source: SourceId) -> String; @@ -327,7 +326,7 @@ impl<'cfg> PackageRegistry<'cfg> { .get_mut(dep.source_id()) .expect("loaded source not present"); - let summaries = match source.query_vec(dep)? { + let summaries = match source.query_vec(dep, QueryKind::Exact)? { Poll::Ready(deps) => deps, Poll::Pending => { deps_pending.push(dep_remaining); @@ -483,7 +482,7 @@ impl<'cfg> PackageRegistry<'cfg> { for &s in self.overrides.iter() { let src = self.sources.get_mut(s).unwrap(); let dep = Dependency::new_override(dep.package_name(), s); - let mut results = match src.query_vec(&dep) { + let mut results = match src.query_vec(&dep, QueryKind::Exact) { Poll::Ready(results) => results?, Poll::Pending => return Poll::Pending, }; @@ -575,8 +574,8 @@ impl<'cfg> Registry for PackageRegistry<'cfg> { fn query( &mut self, dep: &Dependency, + kind: QueryKind, f: &mut dyn FnMut(Summary), - fuzzy: bool, ) -> Poll> { assert!(self.patches_locked); let (override_summary, n, to_warn) = { @@ -671,11 +670,7 @@ impl<'cfg> Registry for PackageRegistry<'cfg> { } f(lock(locked, all_patches, summary)) }; - return if fuzzy { - source.fuzzy_query(dep, callback) - } else { - source.query(dep, callback) - }; + return source.query(dep, kind, callback); } // If we have an override summary then we query the source @@ -694,11 +689,7 @@ impl<'cfg> Registry for PackageRegistry<'cfg> { n += 1; to_warn = Some(summary); }; - let pend = if fuzzy { - source.fuzzy_query(dep, callback)? - } else { - source.query(dep, callback)? - }; + let pend = source.query(dep, kind, callback); if pend.is_pending() { return Poll::Pending; } @@ -889,7 +880,7 @@ fn summary_for_patch( // No summaries found, try to help the user figure out what is wrong. if let Some(locked) = locked { // Since the locked patch did not match anything, try the unlocked one. - let orig_matches = match source.query_vec(orig_patch) { + let orig_matches = match source.query_vec(orig_patch, QueryKind::Exact) { Poll::Pending => return Poll::Pending, Poll::Ready(deps) => deps, } @@ -914,7 +905,7 @@ fn summary_for_patch( // Try checking if there are *any* packages that match this by name. let name_only_dep = Dependency::new_override(orig_patch.package_name(), orig_patch.source_id()); - let name_summaries = match source.query_vec(&name_only_dep) { + let name_summaries = match source.query_vec(&name_only_dep, QueryKind::Exact) { Poll::Pending => return Poll::Pending, Poll::Ready(deps) => deps, } diff --git a/src/cargo/core/resolver/dep_cache.rs b/src/cargo/core/resolver/dep_cache.rs index 067f8f74f3e..79e44f6eba2 100644 --- a/src/cargo/core/resolver/dep_cache.rs +++ b/src/cargo/core/resolver/dep_cache.rs @@ -16,7 +16,9 @@ use crate::core::resolver::{ ActivateError, ActivateResult, CliFeatures, RequestedFeatures, ResolveOpts, VersionOrdering, VersionPreferences, }; -use crate::core::{Dependency, FeatureValue, PackageId, PackageIdSpec, Registry, Summary}; +use crate::core::{ + Dependency, FeatureValue, PackageId, PackageIdSpec, QueryKind, Registry, Summary, +}; use crate::util::errors::CargoResult; use crate::util::interning::InternedString; @@ -100,13 +102,9 @@ impl<'a> RegistryQueryer<'a> { } let mut ret = Vec::new(); - let ready = self.registry.query( - dep, - &mut |s| { - ret.push(s); - }, - false, - )?; + let ready = self.registry.query(dep, QueryKind::Exact, &mut |s| { + ret.push(s); + })?; if ready.is_pending() { self.registry_cache.insert(dep.clone(), Poll::Pending); return Poll::Pending; @@ -127,7 +125,7 @@ impl<'a> RegistryQueryer<'a> { dep.version_req() ); - let mut summaries = match self.registry.query_vec(dep, false)? { + let mut summaries = match self.registry.query_vec(dep, QueryKind::Exact)? { Poll::Ready(s) => s.into_iter(), Poll::Pending => { self.registry_cache.insert(dep.clone(), Poll::Pending); diff --git a/src/cargo/core/resolver/errors.rs b/src/cargo/core/resolver/errors.rs index 306da17ef6c..d75240df625 100644 --- a/src/cargo/core/resolver/errors.rs +++ b/src/cargo/core/resolver/errors.rs @@ -1,7 +1,7 @@ use std::fmt; use std::task::Poll; -use crate::core::{Dependency, PackageId, Registry, Summary}; +use crate::core::{Dependency, PackageId, QueryKind, Registry, Summary}; use crate::util::lev_distance::lev_distance; use crate::util::{Config, VersionExt}; use anyhow::Error; @@ -228,7 +228,7 @@ pub(super) fn activation_error( new_dep.set_version_req(all_req); let mut candidates = loop { - match registry.query_vec(&new_dep, false) { + match registry.query_vec(&new_dep, QueryKind::Exact) { Poll::Ready(Ok(candidates)) => break candidates, Poll::Ready(Err(e)) => return to_resolve_err(e), Poll::Pending => match registry.block_until_ready() { @@ -294,7 +294,7 @@ pub(super) fn activation_error( // Maybe the user mistyped the name? Like `dep-thing` when `Dep_Thing` // was meant. So we try asking the registry for a `fuzzy` search for suggestions. let mut candidates = loop { - match registry.query_vec(&new_dep, true) { + match registry.query_vec(&new_dep, QueryKind::Fuzzy) { Poll::Ready(Ok(candidates)) => break candidates, Poll::Ready(Err(e)) => return to_resolve_err(e), Poll::Pending => match registry.block_until_ready() { diff --git a/src/cargo/core/source/mod.rs b/src/cargo/core/source/mod.rs index 56dfcb902ae..229e6cdea0c 100644 --- a/src/cargo/core/source/mod.rs +++ b/src/cargo/core/source/mod.rs @@ -29,21 +29,16 @@ pub trait Source { fn requires_precise(&self) -> bool; /// Attempts to find the packages that match a dependency request. - fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> Poll>; - - /// Attempts to find the packages that are close to a dependency request. - /// Each source gets to define what `close` means for it. - /// Path/Git sources may return all dependencies that are at that URI, - /// whereas an `Index` source may return dependencies that have the same canonicalization. - fn fuzzy_query( + fn query( &mut self, dep: &Dependency, + kind: QueryKind, f: &mut dyn FnMut(Summary), ) -> Poll>; - fn query_vec(&mut self, dep: &Dependency) -> Poll>> { + fn query_vec(&mut self, dep: &Dependency, kind: QueryKind) -> Poll>> { let mut ret = Vec::new(); - self.query(dep, &mut |s| ret.push(s)).map_ok(|_| ret) + self.query(dep, kind, &mut |s| ret.push(s)).map_ok(|_| ret) } /// Ensure that the source is fully up-to-date for the current session on the next query. @@ -115,6 +110,15 @@ pub trait Source { fn block_until_ready(&mut self) -> CargoResult<()>; } +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum QueryKind { + Exact, + /// Each source gets to define what `close` means for it. + /// Path/Git sources may return all dependencies that are at that URI, + /// whereas an `Index` source may return dependencies that have the same canonicalization. + Fuzzy, +} + pub enum MaybePackage { Ready(Package), Download { url: String, descriptor: String }, @@ -142,17 +146,13 @@ impl<'a, T: Source + ?Sized + 'a> Source for Box { } /// Forwards to `Source::query`. - fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> Poll> { - (**self).query(dep, f) - } - - /// Forwards to `Source::query`. - fn fuzzy_query( + fn query( &mut self, dep: &Dependency, + kind: QueryKind, f: &mut dyn FnMut(Summary), ) -> Poll> { - (**self).fuzzy_query(dep, f) + (**self).query(dep, kind, f) } fn invalidate_cache(&mut self) { @@ -216,16 +216,13 @@ impl<'a, T: Source + ?Sized + 'a> Source for &'a mut T { (**self).requires_precise() } - fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> Poll> { - (**self).query(dep, f) - } - - fn fuzzy_query( + fn query( &mut self, dep: &Dependency, + kind: QueryKind, f: &mut dyn FnMut(Summary), ) -> Poll> { - (**self).fuzzy_query(dep, f) + (**self).query(dep, kind, f) } fn invalidate_cache(&mut self) { diff --git a/src/cargo/ops/cargo_add/mod.rs b/src/cargo/ops/cargo_add/mod.rs index dff93e91b02..a1cc0d272aa 100644 --- a/src/cargo/ops/cargo_add/mod.rs +++ b/src/cargo/ops/cargo_add/mod.rs @@ -19,6 +19,7 @@ use toml_edit::Item as TomlItem; use crate::core::dependency::DepKind; use crate::core::registry::PackageRegistry; use crate::core::Package; +use crate::core::QueryKind; use crate::core::Registry; use crate::core::Shell; use crate::core::Workspace; @@ -443,8 +444,7 @@ fn get_latest_dependency( } MaybeWorkspace::Other(query) => { let possibilities = loop { - let fuzzy = true; - match registry.query_vec(&query, fuzzy) { + match registry.query_vec(&query, QueryKind::Fuzzy) { std::task::Poll::Ready(res) => { break res?; } @@ -485,8 +485,8 @@ fn select_package( } MaybeWorkspace::Other(query) => { let possibilities = loop { - let fuzzy = false; // Returns all for path/git - match registry.query_vec(&query, fuzzy) { + // Exact to avoid returning all for path/git + match registry.query_vec(&query, QueryKind::Exact) { std::task::Poll::Ready(res) => { break res?; } @@ -600,7 +600,7 @@ fn populate_available_features( MaybeWorkspace::Other(query) => query, }; let possibilities = loop { - match registry.query_vec(&query, true) { + match registry.query_vec(&query, QueryKind::Fuzzy) { std::task::Poll::Ready(res) => { break res?; } diff --git a/src/cargo/ops/common_for_install_and_uninstall.rs b/src/cargo/ops/common_for_install_and_uninstall.rs index 362a2d96450..08d5c908979 100644 --- a/src/cargo/ops/common_for_install_and_uninstall.rs +++ b/src/cargo/ops/common_for_install_and_uninstall.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; use toml_edit::easy as toml; use crate::core::compiler::Freshness; -use crate::core::{Dependency, FeatureValue, Package, PackageId, Source, SourceId}; +use crate::core::{Dependency, FeatureValue, Package, PackageId, QueryKind, Source, SourceId}; use crate::ops::{self, CompileFilter, CompileOptions}; use crate::sources::PathSource; use crate::util::errors::CargoResult; @@ -540,7 +540,7 @@ where } let deps = loop { - match source.query_vec(&dep)? { + match source.query_vec(&dep, QueryKind::Exact)? { Poll::Ready(deps) => break deps, Poll::Pending => source.block_until_ready()?, } diff --git a/src/cargo/sources/directory.rs b/src/cargo/sources/directory.rs index d6f96cc9003..e30755643a7 100644 --- a/src/cargo/sources/directory.rs +++ b/src/cargo/sources/directory.rs @@ -4,7 +4,7 @@ use std::path::{Path, PathBuf}; use std::task::Poll; use crate::core::source::MaybePackage; -use crate::core::{Dependency, Package, PackageId, Source, SourceId, Summary}; +use crate::core::{Dependency, Package, PackageId, QueryKind, Source, SourceId, Summary}; use crate::sources::PathSource; use crate::util::errors::CargoResult; use crate::util::Config; @@ -46,28 +46,21 @@ impl<'cfg> Debug for DirectorySource<'cfg> { } impl<'cfg> Source for DirectorySource<'cfg> { - fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> Poll> { - if !self.updated { - return Poll::Pending; - } - let packages = self.packages.values().map(|p| &p.0); - let matches = packages.filter(|pkg| dep.matches(pkg.summary())); - for summary in matches.map(|pkg| pkg.summary().clone()) { - f(summary); - } - Poll::Ready(Ok(())) - } - - fn fuzzy_query( + fn query( &mut self, - _dep: &Dependency, + dep: &Dependency, + kind: QueryKind, f: &mut dyn FnMut(Summary), ) -> Poll> { if !self.updated { return Poll::Pending; } let packages = self.packages.values().map(|p| &p.0); - for summary in packages.map(|pkg| pkg.summary().clone()) { + let matches = packages.filter(|pkg| match kind { + QueryKind::Exact => dep.matches(pkg.summary()), + QueryKind::Fuzzy => true, + }); + for summary in matches.map(|pkg| pkg.summary().clone()) { f(summary); } Poll::Ready(Ok(())) diff --git a/src/cargo/sources/git/source.rs b/src/cargo/sources/git/source.rs index 5a8849990d1..4644a3ac710 100644 --- a/src/cargo/sources/git/source.rs +++ b/src/cargo/sources/git/source.rs @@ -1,4 +1,4 @@ -use crate::core::source::{MaybePackage, Source, SourceId}; +use crate::core::source::{MaybePackage, QueryKind, Source, SourceId}; use crate::core::GitReference; use crate::core::{Dependency, Package, PackageId, Summary}; use crate::sources::git::utils::GitRemote; @@ -86,21 +86,14 @@ impl<'cfg> Debug for GitSource<'cfg> { } impl<'cfg> Source for GitSource<'cfg> { - fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> Poll> { - if let Some(src) = self.path_source.as_mut() { - src.query(dep, f) - } else { - Poll::Pending - } - } - - fn fuzzy_query( + fn query( &mut self, dep: &Dependency, + kind: QueryKind, f: &mut dyn FnMut(Summary), ) -> Poll> { if let Some(src) = self.path_source.as_mut() { - src.fuzzy_query(dep, f) + src.query(dep, kind, f) } else { Poll::Pending } diff --git a/src/cargo/sources/path.rs b/src/cargo/sources/path.rs index fcbae46088e..78a66e098ec 100644 --- a/src/cargo/sources/path.rs +++ b/src/cargo/sources/path.rs @@ -4,7 +4,7 @@ use std::path::{Path, PathBuf}; use std::task::Poll; use crate::core::source::MaybePackage; -use crate::core::{Dependency, Package, PackageId, Source, SourceId, Summary}; +use crate::core::{Dependency, Package, PackageId, QueryKind, Source, SourceId, Summary}; use crate::ops; use crate::util::{internal, CargoResult, Config}; use anyhow::Context as _; @@ -497,24 +497,21 @@ impl<'cfg> Debug for PathSource<'cfg> { } impl<'cfg> Source for PathSource<'cfg> { - fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> Poll> { - self.update()?; - for s in self.packages.iter().map(|p| p.summary()) { - if dep.matches(s) { - f(s.clone()) - } - } - Poll::Ready(Ok(())) - } - - fn fuzzy_query( + fn query( &mut self, - _dep: &Dependency, + dep: &Dependency, + kind: QueryKind, f: &mut dyn FnMut(Summary), ) -> Poll> { self.update()?; for s in self.packages.iter().map(|p| p.summary()) { - f(s.clone()) + let matched = match kind { + QueryKind::Exact => dep.matches(s), + QueryKind::Fuzzy => true, + }; + if matched { + f(s.clone()) + } } Poll::Ready(Ok(())) } diff --git a/src/cargo/sources/registry/mod.rs b/src/cargo/sources/registry/mod.rs index 899c4e73c22..c17b822fd0f 100644 --- a/src/cargo/sources/registry/mod.rs +++ b/src/cargo/sources/registry/mod.rs @@ -176,7 +176,7 @@ use tar::Archive; use crate::core::dependency::{DepKind, Dependency}; use crate::core::source::MaybePackage; -use crate::core::{Package, PackageId, Source, SourceId, Summary}; +use crate::core::{Package, PackageId, QueryKind, Source, SourceId, Summary}; use crate::sources::PathSource; use crate::util::hex; use crate::util::interning::InternedString; @@ -701,12 +701,18 @@ impl<'cfg> RegistrySource<'cfg> { } impl<'cfg> Source for RegistrySource<'cfg> { - fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> Poll> { + fn query( + &mut self, + dep: &Dependency, + kind: QueryKind, + f: &mut dyn FnMut(Summary), + ) -> Poll> { // If this is a precise dependency, then it came from a lock file and in // theory the registry is known to contain this version. If, however, we // come back with no summaries, then our registry may need to be // updated, so we fall back to performing a lazy update. - if dep.source_id().precise().is_some() && !self.ops.is_updated() { + if kind == QueryKind::Exact && dep.source_id().precise().is_some() && !self.ops.is_updated() + { debug!("attempting query without update"); let mut called = false; let pend = @@ -731,21 +737,16 @@ impl<'cfg> Source for RegistrySource<'cfg> { self.index .query_inner(dep, &mut *self.ops, &self.yanked_whitelist, &mut |s| { - if dep.matches(&s) { + let matched = match kind { + QueryKind::Exact => dep.matches(&s), + QueryKind::Fuzzy => true, + }; + if matched { f(s); } }) } - fn fuzzy_query( - &mut self, - dep: &Dependency, - f: &mut dyn FnMut(Summary), - ) -> Poll> { - self.index - .query_inner(dep, &mut *self.ops, &self.yanked_whitelist, f) - } - fn supports_checksums(&self) -> bool { true } diff --git a/src/cargo/sources/replaced.rs b/src/cargo/sources/replaced.rs index 0bbbd6f181f..2d8a2903d76 100644 --- a/src/cargo/sources/replaced.rs +++ b/src/cargo/sources/replaced.rs @@ -1,5 +1,5 @@ use crate::core::source::MaybePackage; -use crate::core::{Dependency, Package, PackageId, Source, SourceId, Summary}; +use crate::core::{Dependency, Package, PackageId, QueryKind, Source, SourceId, Summary}; use crate::util::errors::CargoResult; use std::task::Poll; @@ -42,32 +42,17 @@ impl<'cfg> Source for ReplacedSource<'cfg> { self.inner.requires_precise() } - fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> Poll> { - let (replace_with, to_replace) = (self.replace_with, self.to_replace); - let dep = dep.clone().map_source(to_replace, replace_with); - - self.inner - .query(&dep, &mut |summary| { - f(summary.map_source(replace_with, to_replace)) - }) - .map_err(|e| { - e.context(format!( - "failed to query replaced source {}", - self.to_replace - )) - }) - } - - fn fuzzy_query( + fn query( &mut self, dep: &Dependency, + kind: QueryKind, f: &mut dyn FnMut(Summary), ) -> Poll> { let (replace_with, to_replace) = (self.replace_with, self.to_replace); let dep = dep.clone().map_source(to_replace, replace_with); self.inner - .fuzzy_query(&dep, &mut |summary| { + .query(&dep, kind, &mut |summary| { f(summary.map_source(replace_with, to_replace)) }) .map_err(|e| {