Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions crates/xtask-bump-check/src/xtask.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,10 @@ fn check_crates_io<'a>(
let possibilities =
futures::executor::block_on(registry.query_vec(&query, QueryKind::Exact))?
.into_iter()
.filter(|s| matches!(s, IndexSummary::Candidate(_)))
.filter_map(|s| match s {
IndexSummary::Candidate(s) => Some(s),
_ => None,
})
.collect::<Vec<_>>();
if possibilities.is_empty() {
tracing::trace!("dep `{name}` has no version greater than or equal to `{current}`");
Expand All @@ -457,7 +460,6 @@ fn check_crates_io<'a>(
"`{name}@{current}` needs a bump because its should have a version newer than crates.io: {:?}`",
possibilities
.iter()
.map(|s| s.as_summary())
.map(|s| format!("{}@{}", s.name(), s.version()))
.collect::<Vec<_>>(),
);
Expand Down
27 changes: 17 additions & 10 deletions src/cargo/core/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ impl<'gctx> PackageRegistry<'gctx> {
}

/// Queries path overrides from this registry.
async fn query_overrides(&self, dep: &Dependency) -> CargoResult<Option<IndexSummary>> {
async fn query_overrides(&self, dep: &Dependency) -> CargoResult<Option<Summary>> {
let overrides = self.overrides.borrow();
for &s in overrides.iter() {
let dep = Dependency::new_override(dep.package_name(), s);
Expand All @@ -562,7 +562,7 @@ impl<'gctx> PackageRegistry<'gctx> {
.get(s)
.unwrap()
.query(&dep, QueryKind::Exact, &mut |s| {
if let IndexSummary::Candidate(_) = &s {
if let IndexSummary::Candidate(s) = s {
results = Some(s);
}
})
Expand Down Expand Up @@ -686,10 +686,9 @@ impl<'gctx> Registry for PackageRegistry<'gctx> {
let patch = patches.remove(0);
match override_summary {
Some(override_summary) => {
self.warn_bad_override(override_summary.as_summary(), &patch)?;
let override_summary =
override_summary.map_summary(|summary| self.lock(summary));
f(override_summary);
self.warn_bad_override(&override_summary, &patch)?;
let override_summary = self.lock(override_summary);
f(IndexSummary::Candidate(override_summary));
}
None => f(IndexSummary::Candidate(patch)),
}
Expand Down Expand Up @@ -781,17 +780,25 @@ impl<'gctx> Registry for PackageRegistry<'gctx> {
let mut to_warn = None;
let callback = &mut |summary| {
n += 1;
to_warn = Some(summary);
match summary {
IndexSummary::Candidate(summary)
| IndexSummary::Yanked(summary)
| IndexSummary::Offline(summary)
| IndexSummary::Unsupported(summary, _)
| IndexSummary::Invalid(summary) => {
to_warn = Some(summary);
}
}
};
query_with_context(&*source, dep, kind, callback).await?;
if n > 1 {
return Err(anyhow::anyhow!("found an override with a non-locked list"));
}
if let Some(to_warn) = to_warn {
self.warn_bad_override(override_summary.as_summary(), to_warn.as_summary())?;
self.warn_bad_override(&override_summary, &to_warn)?;
}
let override_summary = override_summary.map_summary(|summary| self.lock(summary));
f(override_summary);
let override_summary = self.lock(override_summary);
f(IndexSummary::Candidate(override_summary));
}
}

Expand Down
10 changes: 8 additions & 2 deletions src/cargo/core/resolver/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ fn rejected_versions(
Ok(candidates) => candidates,
Err(e) => return Some(Err(e)),
};
version_candidates.sort_unstable_by_key(|a| a.as_summary().version().clone());
version_candidates.sort_unstable_by_key(|a| a.package_id().version().clone());
if version_candidates.is_empty() {
None
} else {
Expand All @@ -486,7 +486,13 @@ fn alt_names(
};
let mut name_candidates: Vec<_> = name_candidates
.into_iter()
.map(|s| s.into_summary())
.map(|s| match s {
IndexSummary::Candidate(sum)
| IndexSummary::Yanked(sum)
| IndexSummary::Offline(sum)
| IndexSummary::Unsupported(sum, _)
| IndexSummary::Invalid(sum) => sum,
})
.collect();
name_candidates.sort_unstable_by_key(|a| a.name());
name_candidates.dedup_by(|a, b| a.name() == b.name());
Expand Down
15 changes: 9 additions & 6 deletions src/cargo/ops/registry/info/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
use anyhow::bail;
use cargo_util_schemas::core::{PackageIdSpec, PartialVersion};

use crate::core::Summary;
use crate::core::registry::PackageRegistry;
use crate::core::{Dependency, Package, PackageId, PackageIdSpecQuery, Registry, Workspace};
use crate::ops::registry::info::view::pretty_view;
use crate::ops::registry::{RegistryOrIndex, RegistrySourceIds, get_source_id_with_package_id};
use crate::ops::resolve_ws;
use crate::sources::IndexSummary;
use crate::sources::SourceConfigMap;
use crate::sources::source::QueryKind;
use crate::sources::{IndexSummary, SourceConfigMap};
use crate::util::cache_lock::CacheLockMode;
use crate::util::command_prelude::root_manifest;
use crate::{CargoResult, GlobalContext};
Expand Down Expand Up @@ -170,7 +172,7 @@ fn find_pkgid_in_ws(
}

fn find_pkgid_in_summaries(
summaries: &[IndexSummary],
summaries: &[Summary],
normalized_spec: &PackageIdSpec,
rustc_version: &PartialVersion,
source_ids: &RegistrySourceIds,
Expand All @@ -181,12 +183,10 @@ fn find_pkgid_in_summaries(
.max_by(|s1, s2| {
// Check the MSRV compatibility.
let s1_matches = s1
.as_summary()
.rust_version()
.map(|v| v.is_compatible_with(rustc_version))
.unwrap_or_else(|| false);
let s2_matches = s2
.as_summary()
.rust_version()
.map(|v| v.is_compatible_with(rustc_version))
.unwrap_or_else(|| false);
Expand Down Expand Up @@ -216,13 +216,16 @@ fn query_summaries(
spec: &PackageIdSpec,
registry: &mut PackageRegistry<'_>,
source_ids: &RegistrySourceIds,
) -> CargoResult<(Vec<IndexSummary>, Option<String>)> {
) -> CargoResult<(Vec<Summary>, Option<String>)> {
// Query without version requirement to get all index summaries.
let dep = Dependency::parse(spec.name(), None, source_ids.original)?;
// Use normalized crate name lookup for user-provided package names.
let results: Vec<_> = crate::util::block_on(registry.query_vec(&dep, QueryKind::Normalized))?
.into_iter()
.filter(|s| matches!(s, IndexSummary::Candidate(_)))
.filter_map(|s| match s {
IndexSummary::Candidate(s) => Some(s),
_ => None,
})
.collect();

let normalized_name = results.first().map(|s| s.package_id().name().to_string());
Expand Down
19 changes: 8 additions & 11 deletions src/cargo/ops/registry/info/view.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
use std::collections::HashMap;
use std::io::Write;

use crate::core::Summary;
use crate::util::style::{CONTEXT, ERROR, HEADER, LITERAL, NOP, WARN};
use crate::{
CargoResult, GlobalContext,
core::{Dependency, FeatureMap, Package, PackageId, SourceId, dependency::DepKind},
sources::IndexSummary,
util::interning::InternedString,
};

use cargo_util_terminal::{Shell, Verbosity};

// Pretty print the package information.
pub(super) fn pretty_view(
package: &Package,
summaries: &[IndexSummary],
summaries: &[Summary],
suggest_cargo_tree_command: bool,
gctx: &GlobalContext,
) -> CargoResult<()> {
Expand Down Expand Up @@ -60,23 +61,19 @@ pub(super) fn pretty_view(
// 1. The package version is not the latest available version.
// 2. The package source is not crates.io.
match (
summaries.iter().max_by_key(|s| s.as_summary().version()),
summaries.iter().max_by_key(|s| s.version()),
is_package_from_crates_io,
) {
(Some(latest), false) if latest.as_summary().version() != package_id.version() => {
(Some(latest), false) if latest.version() != package_id.version() => {
write!(
stdout,
" {warn}(latest {} {warn:#}{context}from {}{context:#}{warn}){warn:#}",
latest.as_summary().version(),
latest.version(),
pretty_source(summary.source_id(), gctx)
)?;
}
(Some(latest), true) if latest.as_summary().version() != package_id.version() => {
write!(
stdout,
" {warn}(latest {}){warn:#}",
latest.as_summary().version(),
)?;
(Some(latest), true) if latest.version() != package_id.version() => {
write!(stdout, " {warn}(latest {}){warn:#}", latest.version(),)?;
}
(_, false) => {
write!(
Expand Down
4 changes: 2 additions & 2 deletions src/cargo/sources/overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,15 @@ impl<'gctx> Source for DependencyConfusionThreatOverlaySource<'gctx> {
let mut local_packages = std::collections::HashSet::new();
let mut local_callback = |index: IndexSummary| {
let index = index.map_summary(|s| s.map_source(local_source, remote_source));
local_packages.insert(index.as_summary().clone());
local_packages.insert(index.clone());
f(index)
};
self.local
.query(&local_dep, kind, &mut local_callback)
.await?;

let mut remote_callback = |index: IndexSummary| {
if local_packages.contains(index.as_summary()) {
if local_packages.contains(&index) {
tracing::debug!(?local_source, ?remote_source, ?index, "package collision");
} else {
f(index)
Expand Down
25 changes: 8 additions & 17 deletions src/cargo/sources/registry/index/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ enum MaybeIndexSummary {
/// from a line from a raw index file, or a JSON blob from on-disk index cache.
///
/// In addition to a full [`Summary`], we have information on whether it is `yanked`.
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]

@epage epage Jun 11, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some worries about this being accidentally misused but we aren't translating Yanked to Candidate or the other way around, so it should probably be fine?

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we feel it may be misused probably we should not do this?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do translate whatever to Offline though. If we want to add IndexSummary::TooNew we may need some sort of translation from Candidate to that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure about TooNew. The other states are determined by the Source while TooNew wouldn't be.

pub enum IndexSummary {
/// Available for consideration
Candidate(Summary),
Expand All @@ -145,19 +145,10 @@ pub enum IndexSummary {
}

impl IndexSummary {
/// Extract the summary from any variant
pub fn as_summary(&self) -> &Summary {
match self {
IndexSummary::Candidate(sum)
| IndexSummary::Yanked(sum)
| IndexSummary::Offline(sum)
| IndexSummary::Unsupported(sum, _)
| IndexSummary::Invalid(sum) => sum,
}
}

/// Extract the summary from any variant
pub fn into_summary(self) -> Summary {
/// Extract the summary from any variant.
///
/// You should not use this unless you know what you are doing.
fn as_summary_unchecked(&self) -> &Summary {
match self {
IndexSummary::Candidate(sum)
| IndexSummary::Yanked(sum)
Expand All @@ -179,7 +170,7 @@ impl IndexSummary {

/// Extract the package id from any variant
pub fn package_id(&self) -> PackageId {
self.as_summary().package_id()
self.as_summary_unchecked().package_id()
}

/// Returns `true` if the index summary is [`Yanked`].
Expand Down Expand Up @@ -273,7 +264,7 @@ impl<'gctx> RegistryIndex<'gctx> {
Ok(summary
.next()
.ok_or_else(|| internal(format!("no hash listed for {}", pkg)))?
.as_summary()
.as_summary_unchecked()
.checksum()
.map(|checksum| checksum.to_string())
.ok_or_else(|| internal(format!("no hash listed for {}", pkg)))?)
Expand Down Expand Up @@ -498,7 +489,7 @@ impl<'gctx> RegistryIndex<'gctx> {
if online || load.is_crate_downloaded(s.package_id()) {
s.clone()
} else {
IndexSummary::Offline(s.as_summary().clone())
IndexSummary::Offline(s.as_summary_unchecked().clone())
}
})
.for_each(f);
Expand Down
24 changes: 16 additions & 8 deletions src/cargo/sources/registry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,12 +710,13 @@ impl<'gctx> Source for RegistrySource<'gctx> {
if kind == QueryKind::Exact && req.is_locked() && !self.ops.is_updated() {
debug!("attempting query without update");
self.index
.query_inner(dep.package_name(), &req, &*self.ops, &mut |s| {
if matches!(s, IndexSummary::Candidate(_) | IndexSummary::Yanked(_))
&& dep.matches(s.as_summary())
{
// We are looking for a package from a lock file so we do not care about yank
callback(s)
.query_inner(dep.package_name(), &req, &*self.ops, &mut |is| {
match &is {
IndexSummary::Candidate(s) | IndexSummary::Yanked(s) if dep.matches(&s) => {
// We are looking for a package from a lock file so we do not care about yank
callback(is)
}
_ => {}
}
})
.await?;
Expand All @@ -738,10 +739,17 @@ impl<'gctx> Source for RegistrySource<'gctx> {
.query_inner(dep.package_name(), &req, &*self.ops, &mut |s| {
let matched = match kind {
QueryKind::Exact | QueryKind::RejectedVersions => {
let s = match &s {
IndexSummary::Candidate(s)
| IndexSummary::Yanked(s)
| IndexSummary::Offline(s)
| IndexSummary::Unsupported(s, _)
| IndexSummary::Invalid(s) => s,
};
if req.is_precise() && self.gctx.cli_unstable().unstable_options {
dep.matches_prerelease(s.as_summary())
dep.matches_prerelease(&s)
} else {
dep.matches(s.as_summary())
dep.matches(&s)
}
}
QueryKind::AlternativeNames => true,
Expand Down
Loading