From c99d8bb2bc2cd7cc50b2c594c183fd01e854883a Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 11 Jun 2026 14:56:30 -0500 Subject: [PATCH 1/3] refactor(diag): Be more specific in stats tracked --- src/cargo/core/compiler/job_queue/mod.rs | 4 +-- src/cargo/diagnostics/mod.rs | 14 +++++------ src/cargo/diagnostics/passes.rs | 25 +++++++++++-------- .../rules/blanket_hint_mostly_unused.rs | 4 +-- .../rules/deferred_parse_diagnostics.rs | 4 +-- src/cargo/diagnostics/rules/im_a_teapot.rs | 4 +-- .../rules/implicit_minimum_version_req.rs | 6 ++--- .../rules/missing_lints_features.rs | 8 +++--- .../rules/missing_lints_inheritance.rs | 4 +-- .../diagnostics/rules/non_kebab_case_bins.rs | 6 ++--- .../rules/non_kebab_case_features.rs | 6 ++--- .../rules/non_kebab_case_packages.rs | 6 ++--- .../rules/non_snake_case_features.rs | 6 ++--- .../rules/non_snake_case_packages.rs | 6 ++--- .../diagnostics/rules/redundant_homepage.rs | 6 ++--- .../diagnostics/rules/redundant_readme.rs | 6 ++--- .../text_direction_codepoint_in_comment.rs | 4 +-- .../text_direction_codepoint_in_literal.rs | 4 +-- src/cargo/diagnostics/rules/unknown_lints.rs | 6 ++--- .../diagnostics/rules/unused_dependencies.rs | 10 ++++---- .../rules/unused_workspace_dependencies.rs | 4 +-- .../rules/unused_workspace_package_fields.rs | 4 +-- 22 files changed, 76 insertions(+), 71 deletions(-) diff --git a/src/cargo/core/compiler/job_queue/mod.rs b/src/cargo/core/compiler/job_queue/mod.rs index 8671190a93d..dbb6304930b 100644 --- a/src/cargo/core/compiler/job_queue/mod.rs +++ b/src/cargo/core/compiler/job_queue/mod.rs @@ -144,7 +144,7 @@ use crate::core::compiler::future_incompat::{ }; use crate::core::resolver::ResolveBehavior; use crate::core::{PackageId, TargetKind}; -use crate::diagnostics::DiagnosticStats; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::rules::unused_dependencies; use crate::util::CargoResult; use crate::util::context::WarningHandling; @@ -844,7 +844,7 @@ impl<'gctx> DrainState<'gctx> { self.progress.clear(); if build_runner.bcx.gctx.cli_unstable().cargo_lints { - let mut global_stats = DiagnosticStats::new(); + let mut global_stats = ScopedDiagnosticStats::new(); drop(unused_dependencies::lint_build_results( build_runner, &mut global_stats, diff --git a/src/cargo/diagnostics/mod.rs b/src/cargo/diagnostics/mod.rs index 3244c7bee55..5dafe51ec8b 100644 --- a/src/cargo/diagnostics/mod.rs +++ b/src/cargo/diagnostics/mod.rs @@ -44,7 +44,7 @@ //! When a diagnostic requires adding a new pass, keep in mind: //! - Support for `build.warnings` //! - When errors should block further evaluation within the pass -//! - Providing a summary at the end, like what is provided by [`DiagnosticStats::report_summary`] +//! - Providing a summary at the end, like what is provided by [`ScopedDiagnosticStats::report_summary`] //! - Prefer data driven passes to simplify adding rules //! - Ensure the pass' lints are in [`rules::LINTS`], e.g. `ensure_parse_passed_in_lints` //! - Prefer evaluating the lint level within the pass @@ -72,13 +72,13 @@ pub use lint::{Lint, LintGroup, LintLevel, LintLevelProduct, LintLevelSource}; pub use report::{AsIndex, get_key_value, get_key_value_span, rel_cwd_manifest_path}; pub use rules::{LINT_GROUPS, LINTS}; -pub struct DiagnosticStats { +pub struct ScopedDiagnosticStats { warning_count: usize, lint_warning_count: usize, error_count: usize, } -impl DiagnosticStats { +impl ScopedDiagnosticStats { pub fn new() -> Self { Self { warning_count: 0, @@ -152,8 +152,8 @@ impl DiagnosticStats { } } -impl std::ops::Add for DiagnosticStats { - type Output = DiagnosticStats; +impl std::ops::Add for ScopedDiagnosticStats { + type Output = ScopedDiagnosticStats; fn add(mut self, rhs: Self) -> Self::Output { self += rhs; @@ -161,9 +161,9 @@ impl std::ops::Add for DiagnosticStats { } } -impl std::ops::AddAssign for DiagnosticStats { +impl std::ops::AddAssign for ScopedDiagnosticStats { fn add_assign(&mut self, rhs: Self) { - let DiagnosticStats { + let ScopedDiagnosticStats { warning_count, lint_warning_count, error_count, diff --git a/src/cargo/diagnostics/passes.rs b/src/cargo/diagnostics/passes.rs index c0281f841fe..2511c689f23 100644 --- a/src/cargo/diagnostics/passes.rs +++ b/src/cargo/diagnostics/passes.rs @@ -7,11 +7,11 @@ use crate::GlobalContext; use crate::core::MaybePackage; use crate::core::Package; use crate::core::Workspace; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevel; use crate::diagnostics::LintLevelProduct; use crate::diagnostics::ManifestFor; +use crate::diagnostics::ScopedDiagnosticStats; #[derive(Clone)] pub enum ParsePassRule<'r> { @@ -39,24 +39,29 @@ pub enum ParsePassRule<'r> { } type FnDiagnosticManifest = - fn(ManifestFor<'_>, &Path, &mut DiagnosticStats, &GlobalContext) -> CargoResult<()>; + fn(ManifestFor<'_>, &Path, &mut ScopedDiagnosticStats, &GlobalContext) -> CargoResult<()>; type FnDiagnosticWorkspace = fn( &Workspace<'_>, &MaybePackage, &Path, - &mut DiagnosticStats, + &mut ScopedDiagnosticStats, &GlobalContext, ) -> CargoResult<()>; -type FnDiagnosticPackage = - fn(&Workspace<'_>, &Package, &Path, &mut DiagnosticStats, &GlobalContext) -> CargoResult<()>; +type FnDiagnosticPackage = fn( + &Workspace<'_>, + &Package, + &Path, + &mut ScopedDiagnosticStats, + &GlobalContext, +) -> CargoResult<()>; type FnLintManifest = fn( manifest: ManifestFor<'_>, manifest_path: &Path, LintLevelProduct, - stats: &mut DiagnosticStats, + stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()>; @@ -65,7 +70,7 @@ type FnLintWorkspace = fn( &MaybePackage, &Path, LintLevelProduct, - &mut DiagnosticStats, + &mut ScopedDiagnosticStats, &GlobalContext, ) -> CargoResult<()>; @@ -74,7 +79,7 @@ type FnLintPackage = fn( &Package, &Path, LintLevelProduct, - &mut DiagnosticStats, + &mut ScopedDiagnosticStats, &GlobalContext, ) -> CargoResult<()>; @@ -112,7 +117,7 @@ fn emit_parse_pkg_diagnostics( path: &Path, rules: &[ParsePassRule<'_>], ) -> CargoResult<()> { - let mut pkg_stats = DiagnosticStats::new(); + let mut pkg_stats = ScopedDiagnosticStats::new(); let toml_lints = pkg .manifest() @@ -177,7 +182,7 @@ fn emit_parse_ws_diagnostics( workspace: &Workspace<'_>, rules: &[ParsePassRule<'_>], ) -> CargoResult<()> { - let mut pkg_stats = DiagnosticStats::new(); + let mut pkg_stats = ScopedDiagnosticStats::new(); let cargo_lints = match workspace.root_maybe() { MaybePackage::Package(pkg) => { diff --git a/src/cargo/diagnostics/rules/blanket_hint_mostly_unused.rs b/src/cargo/diagnostics/rules/blanket_hint_mostly_unused.rs index 059469a17c2..83cab94311b 100644 --- a/src/cargo/diagnostics/rules/blanket_hint_mostly_unused.rs +++ b/src/cargo/diagnostics/rules/blanket_hint_mostly_unused.rs @@ -14,9 +14,9 @@ use crate::CargoResult; use crate::GlobalContext; use crate::core::MaybePackage; use crate::core::Workspace; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevelProduct; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::get_key_value_span; use crate::diagnostics::rel_cwd_manifest_path; @@ -61,7 +61,7 @@ pub(crate) fn lint_workspace( maybe_pkg: &MaybePackage, path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { diff --git a/src/cargo/diagnostics/rules/deferred_parse_diagnostics.rs b/src/cargo/diagnostics/rules/deferred_parse_diagnostics.rs index c0a222b62d2..07f4c2093ae 100644 --- a/src/cargo/diagnostics/rules/deferred_parse_diagnostics.rs +++ b/src/cargo/diagnostics/rules/deferred_parse_diagnostics.rs @@ -5,15 +5,15 @@ use tracing::instrument; use crate::CargoResult; use crate::GlobalContext; use crate::core::MaybePackage; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::ManifestFor; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::rel_cwd_manifest_path; #[instrument(skip_all)] pub(crate) fn diagnose_manifest( manifest: ManifestFor<'_>, manifest_path: &Path, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let warnings = match &manifest { diff --git a/src/cargo/diagnostics/rules/im_a_teapot.rs b/src/cargo/diagnostics/rules/im_a_teapot.rs index 2dc414f78c9..1326b48a395 100644 --- a/src/cargo/diagnostics/rules/im_a_teapot.rs +++ b/src/cargo/diagnostics/rules/im_a_teapot.rs @@ -13,9 +13,9 @@ use crate::GlobalContext; use crate::core::Feature; use crate::core::Package; use crate::core::Workspace; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevelProduct; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::get_key_value_span; use crate::diagnostics::rel_cwd_manifest_path; @@ -35,7 +35,7 @@ pub(crate) fn lint_package( pkg: &Package, path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let manifest = pkg.manifest(); diff --git a/src/cargo/diagnostics/rules/implicit_minimum_version_req.rs b/src/cargo/diagnostics/rules/implicit_minimum_version_req.rs index 83053ac7431..0c87c2e3cb3 100644 --- a/src/cargo/diagnostics/rules/implicit_minimum_version_req.rs +++ b/src/cargo/diagnostics/rules/implicit_minimum_version_req.rs @@ -19,11 +19,11 @@ use crate::core::Manifest; use crate::core::MaybePackage; use crate::core::Package; use crate::core::Workspace; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevel; use crate::diagnostics::LintLevelProduct; use crate::diagnostics::LintLevelSource; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::get_key_value; use crate::diagnostics::rel_cwd_manifest_path; use crate::util::OptVersionReq; @@ -90,7 +90,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -151,7 +151,7 @@ pub(crate) fn lint_workspace( maybe_pkg: &MaybePackage, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { diff --git a/src/cargo/diagnostics/rules/missing_lints_features.rs b/src/cargo/diagnostics/rules/missing_lints_features.rs index c7d78614e8a..e437caf849c 100644 --- a/src/cargo/diagnostics/rules/missing_lints_features.rs +++ b/src/cargo/diagnostics/rules/missing_lints_features.rs @@ -12,8 +12,8 @@ use crate::CargoResult; use crate::GlobalContext; use crate::core::Feature; use crate::core::MaybePackage; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::ManifestFor; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::get_key_value_span; use crate::diagnostics::rel_cwd_manifest_path; @@ -21,7 +21,7 @@ use crate::diagnostics::rel_cwd_manifest_path; pub(crate) fn diagnose_manifest( manifest: ManifestFor<'_>, manifest_path: &Path, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let normalized_toml = match &manifest { @@ -64,7 +64,7 @@ fn diagnose_manifest_inner( manifest: &ManifestFor<'_>, manifest_path: &Path, cargo_lints: &manifest::TomlToolLints, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let manifest_path = rel_cwd_manifest_path(manifest_path, gctx); @@ -104,7 +104,7 @@ fn report_feature_not_enabled( feature_gate: &Feature, manifest: &ManifestFor<'_>, manifest_path: &str, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let dash_feature_name = feature_gate.name().replace("_", "-"); diff --git a/src/cargo/diagnostics/rules/missing_lints_inheritance.rs b/src/cargo/diagnostics/rules/missing_lints_inheritance.rs index 7f918e34b2b..85720909d76 100644 --- a/src/cargo/diagnostics/rules/missing_lints_inheritance.rs +++ b/src/cargo/diagnostics/rules/missing_lints_inheritance.rs @@ -12,9 +12,9 @@ use crate::CargoResult; use crate::GlobalContext; use crate::core::Package; use crate::core::Workspace; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevelProduct; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::rel_cwd_manifest_path; pub static LINT: &Lint = &Lint { @@ -59,7 +59,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { diff --git a/src/cargo/diagnostics/rules/non_kebab_case_bins.rs b/src/cargo/diagnostics/rules/non_kebab_case_bins.rs index e73eeee5e2c..e0d4af5d57a 100644 --- a/src/cargo/diagnostics/rules/non_kebab_case_bins.rs +++ b/src/cargo/diagnostics/rules/non_kebab_case_bins.rs @@ -14,11 +14,11 @@ use crate::GlobalContext; use crate::core::Package; use crate::core::Workspace; use crate::diagnostics::AsIndex; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevel; use crate::diagnostics::LintLevelProduct; use crate::diagnostics::LintLevelSource; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::get_key_value_span; use crate::diagnostics::rel_cwd_manifest_path; @@ -69,7 +69,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -88,7 +88,7 @@ fn lint_package_inner( manifest_path: &str, lint_level: LintLevel, source: LintLevelSource, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let manifest = pkg.manifest(); diff --git a/src/cargo/diagnostics/rules/non_kebab_case_features.rs b/src/cargo/diagnostics/rules/non_kebab_case_features.rs index 524391fd467..d121db72661 100644 --- a/src/cargo/diagnostics/rules/non_kebab_case_features.rs +++ b/src/cargo/diagnostics/rules/non_kebab_case_features.rs @@ -13,11 +13,11 @@ use crate::CargoResult; use crate::GlobalContext; use crate::core::Package; use crate::core::Workspace; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevel; use crate::diagnostics::LintLevelProduct; use crate::diagnostics::LintLevelSource; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::get_key_value_span; use crate::diagnostics::rel_cwd_manifest_path; @@ -64,7 +64,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -82,7 +82,7 @@ fn lint_package_inner( manifest_path: &str, lint_level: LintLevel, source: LintLevelSource, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { for original_name in pkg.summary().features().keys() { diff --git a/src/cargo/diagnostics/rules/non_kebab_case_packages.rs b/src/cargo/diagnostics/rules/non_kebab_case_packages.rs index 186c49172d1..0d5500baccc 100644 --- a/src/cargo/diagnostics/rules/non_kebab_case_packages.rs +++ b/src/cargo/diagnostics/rules/non_kebab_case_packages.rs @@ -13,11 +13,11 @@ use crate::CargoResult; use crate::GlobalContext; use crate::core::Package; use crate::core::Workspace; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevel; use crate::diagnostics::LintLevelProduct; use crate::diagnostics::LintLevelSource; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::get_key_value_span; use crate::diagnostics::rel_cwd_manifest_path; @@ -64,7 +64,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -82,7 +82,7 @@ fn lint_package_inner( manifest_path: &str, lint_level: LintLevel, source: LintLevelSource, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let manifest = pkg.manifest(); diff --git a/src/cargo/diagnostics/rules/non_snake_case_features.rs b/src/cargo/diagnostics/rules/non_snake_case_features.rs index d48a1a01c55..fd8955120ad 100644 --- a/src/cargo/diagnostics/rules/non_snake_case_features.rs +++ b/src/cargo/diagnostics/rules/non_snake_case_features.rs @@ -13,11 +13,11 @@ use crate::CargoResult; use crate::GlobalContext; use crate::core::Package; use crate::core::Workspace; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevel; use crate::diagnostics::LintLevelProduct; use crate::diagnostics::LintLevelSource; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::get_key_value_span; use crate::diagnostics::rel_cwd_manifest_path; @@ -64,7 +64,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -82,7 +82,7 @@ fn lint_package_inner( manifest_path: &str, lint_level: LintLevel, source: LintLevelSource, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { for original_name in pkg.summary().features().keys() { diff --git a/src/cargo/diagnostics/rules/non_snake_case_packages.rs b/src/cargo/diagnostics/rules/non_snake_case_packages.rs index 0f24249b654..faaf48a5d94 100644 --- a/src/cargo/diagnostics/rules/non_snake_case_packages.rs +++ b/src/cargo/diagnostics/rules/non_snake_case_packages.rs @@ -13,11 +13,11 @@ use crate::CargoResult; use crate::GlobalContext; use crate::core::Package; use crate::core::Workspace; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevel; use crate::diagnostics::LintLevelProduct; use crate::diagnostics::LintLevelSource; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::get_key_value_span; use crate::diagnostics::rel_cwd_manifest_path; @@ -64,7 +64,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -82,7 +82,7 @@ fn lint_package_inner( manifest_path: &str, lint_level: LintLevel, source: LintLevelSource, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let manifest = pkg.manifest(); diff --git a/src/cargo/diagnostics/rules/redundant_homepage.rs b/src/cargo/diagnostics/rules/redundant_homepage.rs index e20e43a9850..7a698cc6ff3 100644 --- a/src/cargo/diagnostics/rules/redundant_homepage.rs +++ b/src/cargo/diagnostics/rules/redundant_homepage.rs @@ -14,11 +14,11 @@ use crate::CargoResult; use crate::GlobalContext; use crate::core::Package; use crate::core::Workspace; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevel; use crate::diagnostics::LintLevelProduct; use crate::diagnostics::LintLevelSource; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::get_key_value_span; use crate::diagnostics::rel_cwd_manifest_path; @@ -68,7 +68,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -86,7 +86,7 @@ fn lint_package_inner( manifest_path: &str, lint_level: LintLevel, source: LintLevelSource, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let manifest = pkg.manifest(); diff --git a/src/cargo/diagnostics/rules/redundant_readme.rs b/src/cargo/diagnostics/rules/redundant_readme.rs index 778a435d204..57fc14fcf47 100644 --- a/src/cargo/diagnostics/rules/redundant_readme.rs +++ b/src/cargo/diagnostics/rules/redundant_readme.rs @@ -15,11 +15,11 @@ use crate::CargoResult; use crate::GlobalContext; use crate::core::Package; use crate::core::Workspace; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevel; use crate::diagnostics::LintLevelProduct; use crate::diagnostics::LintLevelSource; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::get_key_value_span; use crate::diagnostics::rel_cwd_manifest_path; use crate::util::toml::DEFAULT_README_FILES; @@ -70,7 +70,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -88,7 +88,7 @@ fn lint_package_inner( manifest_path: &str, lint_level: LintLevel, source: LintLevelSource, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let manifest = pkg.manifest(); diff --git a/src/cargo/diagnostics/rules/text_direction_codepoint_in_comment.rs b/src/cargo/diagnostics/rules/text_direction_codepoint_in_comment.rs index f6cba469faf..70805ca0713 100644 --- a/src/cargo/diagnostics/rules/text_direction_codepoint_in_comment.rs +++ b/src/cargo/diagnostics/rules/text_direction_codepoint_in_comment.rs @@ -16,10 +16,10 @@ use super::CORRECTNESS; use crate::CargoResult; use crate::GlobalContext; use crate::core::MaybePackage; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevelProduct; use crate::diagnostics::ManifestFor; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::rel_cwd_manifest_path; pub static LINT: &Lint = &Lint { @@ -51,7 +51,7 @@ pub(crate) fn lint_manifest( manifest: ManifestFor<'_>, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { diff --git a/src/cargo/diagnostics/rules/text_direction_codepoint_in_literal.rs b/src/cargo/diagnostics/rules/text_direction_codepoint_in_literal.rs index f02b092cff1..c7e8ace3486 100644 --- a/src/cargo/diagnostics/rules/text_direction_codepoint_in_literal.rs +++ b/src/cargo/diagnostics/rules/text_direction_codepoint_in_literal.rs @@ -17,10 +17,10 @@ use super::CORRECTNESS; use crate::CargoResult; use crate::GlobalContext; use crate::core::MaybePackage; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevelProduct; use crate::diagnostics::ManifestFor; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::rel_cwd_manifest_path; pub static LINT: &Lint = &Lint { @@ -52,7 +52,7 @@ pub(crate) fn lint_manifest( manifest: ManifestFor<'_>, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { diff --git a/src/cargo/diagnostics/rules/unknown_lints.rs b/src/cargo/diagnostics/rules/unknown_lints.rs index c879bca6b76..b342e45a4df 100644 --- a/src/cargo/diagnostics/rules/unknown_lints.rs +++ b/src/cargo/diagnostics/rules/unknown_lints.rs @@ -15,10 +15,10 @@ use super::find_lint_or_group; use crate::CargoResult; use crate::GlobalContext; use crate::core::MaybePackage; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevelProduct; use crate::diagnostics::ManifestFor; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::get_key_value_span; use crate::diagnostics::rel_cwd_manifest_path; @@ -53,7 +53,7 @@ pub(crate) fn lint_manifest( manifest: ManifestFor<'_>, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let normalized_toml = match &manifest { @@ -111,7 +111,7 @@ fn lint_manifest_inner( manifest_path: &Path, level: &LintLevelProduct, cargo_lints: &TomlToolLints, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { diff --git a/src/cargo/diagnostics/rules/unused_dependencies.rs b/src/cargo/diagnostics/rules/unused_dependencies.rs index a4b5042c148..8efb5cbac27 100644 --- a/src/cargo/diagnostics/rules/unused_dependencies.rs +++ b/src/cargo/diagnostics/rules/unused_dependencies.rs @@ -23,10 +23,10 @@ use crate::core::compiler::Unit; use crate::core::compiler::unused_deps::DependenciesState; use crate::core::compiler::unused_deps::UnusedDepState; use crate::core::dependency::DepKind; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevel; use crate::diagnostics::LintLevelProduct; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::get_key_value_span; use crate::diagnostics::rel_cwd_manifest_path; @@ -99,7 +99,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -172,7 +172,7 @@ pub(crate) fn lint_package( #[instrument(skip_all)] pub fn lint_build_results( build_runner: &BuildRunner<'_, '_>, - global_stats: &mut DiagnosticStats, + global_stats: &mut ScopedDiagnosticStats, ) -> CargoResult<()> { for (pkg_id, states) in &build_runner.unused_dep_state.states { let Some(pkg) = get_package(&build_runner.unused_dep_state, pkg_id) else { @@ -207,7 +207,7 @@ pub fn lint_build_results( continue; } - let mut pkg_stats = DiagnosticStats::new(); + let mut pkg_stats = ScopedDiagnosticStats::new(); lint_package_build_results(build_runner, pkg, states, level, &mut pkg_stats)?; // HACK: as other rules are added to this pass, this needs to move up into the pass if let Err(error) = @@ -225,7 +225,7 @@ fn lint_package_build_results( pkg: &Package, states: &IndexMap, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, ) -> CargoResult<()> { let mut lint_count = 0; let LintLevelProduct { diff --git a/src/cargo/diagnostics/rules/unused_workspace_dependencies.rs b/src/cargo/diagnostics/rules/unused_workspace_dependencies.rs index 4dfafdd7c93..d924d4e2ab9 100644 --- a/src/cargo/diagnostics/rules/unused_workspace_dependencies.rs +++ b/src/cargo/diagnostics/rules/unused_workspace_dependencies.rs @@ -15,9 +15,9 @@ use crate::CargoResult; use crate::GlobalContext; use crate::core::MaybePackage; use crate::core::Workspace; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevelProduct; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::get_key_value_span; use crate::diagnostics::rel_cwd_manifest_path; @@ -52,7 +52,7 @@ pub(crate) fn lint_workspace( maybe_pkg: &MaybePackage, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { diff --git a/src/cargo/diagnostics/rules/unused_workspace_package_fields.rs b/src/cargo/diagnostics/rules/unused_workspace_package_fields.rs index a924675075c..7ecc2fb0e12 100644 --- a/src/cargo/diagnostics/rules/unused_workspace_package_fields.rs +++ b/src/cargo/diagnostics/rules/unused_workspace_package_fields.rs @@ -14,9 +14,9 @@ use crate::CargoResult; use crate::GlobalContext; use crate::core::MaybePackage; use crate::core::Workspace; -use crate::diagnostics::DiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevelProduct; +use crate::diagnostics::ScopedDiagnosticStats; use crate::diagnostics::get_key_value_span; use crate::diagnostics::rel_cwd_manifest_path; @@ -52,7 +52,7 @@ pub(crate) fn lint_workspace( maybe_pkg: &MaybePackage, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut DiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { From e5d4531d85017eff8fcd368ac27a83eb8d4f769f Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 11 Jun 2026 15:06:46 -0500 Subject: [PATCH 2/3] refactor(diag): Split stats into scoped and global --- src/cargo/core/compiler/job_queue/mod.rs | 4 +- src/cargo/diagnostics/mod.rs | 49 +++++++++---------- src/cargo/diagnostics/passes.rs | 24 +++++---- .../rules/blanket_hint_mostly_unused.rs | 2 +- .../rules/deferred_parse_diagnostics.rs | 2 +- src/cargo/diagnostics/rules/im_a_teapot.rs | 2 +- .../rules/implicit_minimum_version_req.rs | 4 +- .../rules/missing_lints_features.rs | 6 +-- .../rules/missing_lints_inheritance.rs | 2 +- .../diagnostics/rules/non_kebab_case_bins.rs | 4 +- .../rules/non_kebab_case_features.rs | 4 +- .../rules/non_kebab_case_packages.rs | 4 +- .../rules/non_snake_case_features.rs | 4 +- .../rules/non_snake_case_packages.rs | 4 +- .../diagnostics/rules/redundant_homepage.rs | 4 +- .../diagnostics/rules/redundant_readme.rs | 4 +- .../text_direction_codepoint_in_comment.rs | 2 +- .../text_direction_codepoint_in_literal.rs | 2 +- src/cargo/diagnostics/rules/unknown_lints.rs | 4 +- .../diagnostics/rules/unused_dependencies.rs | 10 ++-- .../rules/unused_workspace_dependencies.rs | 2 +- .../rules/unused_workspace_package_fields.rs | 2 +- 22 files changed, 72 insertions(+), 73 deletions(-) diff --git a/src/cargo/core/compiler/job_queue/mod.rs b/src/cargo/core/compiler/job_queue/mod.rs index dbb6304930b..ad0c3e37844 100644 --- a/src/cargo/core/compiler/job_queue/mod.rs +++ b/src/cargo/core/compiler/job_queue/mod.rs @@ -144,7 +144,7 @@ use crate::core::compiler::future_incompat::{ }; use crate::core::resolver::ResolveBehavior; use crate::core::{PackageId, TargetKind}; -use crate::diagnostics::ScopedDiagnosticStats; +use crate::diagnostics::GlobalDiagnosticStats; use crate::diagnostics::rules::unused_dependencies; use crate::util::CargoResult; use crate::util::context::WarningHandling; @@ -844,7 +844,7 @@ impl<'gctx> DrainState<'gctx> { self.progress.clear(); if build_runner.bcx.gctx.cli_unstable().cargo_lints { - let mut global_stats = ScopedDiagnosticStats::new(); + let mut global_stats = GlobalDiagnosticStats::new(); drop(unused_dependencies::lint_build_results( build_runner, &mut global_stats, diff --git a/src/cargo/diagnostics/mod.rs b/src/cargo/diagnostics/mod.rs index 5dafe51ec8b..4c636ee4c21 100644 --- a/src/cargo/diagnostics/mod.rs +++ b/src/cargo/diagnostics/mod.rs @@ -72,21 +72,37 @@ pub use lint::{Lint, LintGroup, LintLevel, LintLevelProduct, LintLevelSource}; pub use report::{AsIndex, get_key_value, get_key_value_span, rel_cwd_manifest_path}; pub use rules::{LINT_GROUPS, LINTS}; -pub struct ScopedDiagnosticStats { - warning_count: usize, - lint_warning_count: usize, +pub struct GlobalDiagnosticStats { error_count: usize, } -impl ScopedDiagnosticStats { +impl GlobalDiagnosticStats { pub fn new() -> Self { - Self { + Self { error_count: 0 } + } + + pub fn scope(&mut self) -> ScopedDiagnosticStats<'_> { + ScopedDiagnosticStats { warning_count: 0, lint_warning_count: 0, error_count: 0, + global: self, } } + pub fn error_count(&self) -> usize { + self.error_count + } +} + +pub struct ScopedDiagnosticStats<'g> { + warning_count: usize, + lint_warning_count: usize, + error_count: usize, + global: &'g mut GlobalDiagnosticStats, +} + +impl ScopedDiagnosticStats<'_> { pub fn lint_warning_count(&self) -> usize { self.lint_warning_count } @@ -105,6 +121,7 @@ impl ScopedDiagnosticStats { pub fn record_error(&mut self) { self.error_count += 1; + self.global.error_count += 1; } pub fn record_lint(&mut self, lint: LintLevel) { @@ -152,28 +169,6 @@ impl ScopedDiagnosticStats { } } -impl std::ops::Add for ScopedDiagnosticStats { - type Output = ScopedDiagnosticStats; - - fn add(mut self, rhs: Self) -> Self::Output { - self += rhs; - self - } -} - -impl std::ops::AddAssign for ScopedDiagnosticStats { - fn add_assign(&mut self, rhs: Self) { - let ScopedDiagnosticStats { - warning_count, - lint_warning_count, - error_count, - } = rhs; - self.warning_count += warning_count; - self.lint_warning_count += lint_warning_count; - self.error_count += error_count; - } -} - /// Scope at which a lint runs: package-level or workspace-level. pub enum ManifestFor<'a> { /// Lint runs for a specific package. diff --git a/src/cargo/diagnostics/passes.rs b/src/cargo/diagnostics/passes.rs index 2511c689f23..369a9445568 100644 --- a/src/cargo/diagnostics/passes.rs +++ b/src/cargo/diagnostics/passes.rs @@ -7,6 +7,7 @@ use crate::GlobalContext; use crate::core::MaybePackage; use crate::core::Package; use crate::core::Workspace; +use crate::diagnostics::GlobalDiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevel; use crate::diagnostics::LintLevelProduct; @@ -39,13 +40,13 @@ pub enum ParsePassRule<'r> { } type FnDiagnosticManifest = - fn(ManifestFor<'_>, &Path, &mut ScopedDiagnosticStats, &GlobalContext) -> CargoResult<()>; + fn(ManifestFor<'_>, &Path, &mut ScopedDiagnosticStats<'_>, &GlobalContext) -> CargoResult<()>; type FnDiagnosticWorkspace = fn( &Workspace<'_>, &MaybePackage, &Path, - &mut ScopedDiagnosticStats, + &mut ScopedDiagnosticStats<'_>, &GlobalContext, ) -> CargoResult<()>; @@ -53,7 +54,7 @@ type FnDiagnosticPackage = fn( &Workspace<'_>, &Package, &Path, - &mut ScopedDiagnosticStats, + &mut ScopedDiagnosticStats<'_>, &GlobalContext, ) -> CargoResult<()>; @@ -61,7 +62,7 @@ type FnLintManifest = fn( manifest: ManifestFor<'_>, manifest_path: &Path, LintLevelProduct, - stats: &mut ScopedDiagnosticStats, + stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()>; @@ -70,7 +71,7 @@ type FnLintWorkspace = fn( &MaybePackage, &Path, LintLevelProduct, - &mut ScopedDiagnosticStats, + &mut ScopedDiagnosticStats<'_>, &GlobalContext, ) -> CargoResult<()>; @@ -79,7 +80,7 @@ type FnLintPackage = fn( &Package, &Path, LintLevelProduct, - &mut ScopedDiagnosticStats, + &mut ScopedDiagnosticStats<'_>, &GlobalContext, ) -> CargoResult<()>; @@ -87,16 +88,17 @@ pub fn emit_parse_diagnostics( workspace: &Workspace<'_>, rules: &[ParsePassRule<'_>], ) -> CargoResult<()> { + let mut stats = GlobalDiagnosticStats::new(); let mut first_emitted_error = None; - if let Err(e) = emit_parse_ws_diagnostics(workspace, rules) { + if let Err(e) = emit_parse_ws_diagnostics(workspace, rules, &mut stats) { first_emitted_error = Some(e); } for maybe_pkg in workspace.loaded_maybe() { if let MaybePackage::Package(pkg) = maybe_pkg { let path = pkg.manifest_path(); - if let Err(e) = emit_parse_pkg_diagnostics(workspace, pkg, &path, rules) + if let Err(e) = emit_parse_pkg_diagnostics(workspace, pkg, &path, rules, &mut stats) && first_emitted_error.is_none() { first_emitted_error = Some(e); @@ -116,8 +118,9 @@ fn emit_parse_pkg_diagnostics( pkg: &Package, path: &Path, rules: &[ParsePassRule<'_>], + global_stats: &mut GlobalDiagnosticStats, ) -> CargoResult<()> { - let mut pkg_stats = ScopedDiagnosticStats::new(); + let mut pkg_stats = global_stats.scope(); let toml_lints = pkg .manifest() @@ -181,8 +184,9 @@ fn emit_parse_pkg_diagnostics( fn emit_parse_ws_diagnostics( workspace: &Workspace<'_>, rules: &[ParsePassRule<'_>], + global_stats: &mut GlobalDiagnosticStats, ) -> CargoResult<()> { - let mut pkg_stats = ScopedDiagnosticStats::new(); + let mut pkg_stats = global_stats.scope(); let cargo_lints = match workspace.root_maybe() { MaybePackage::Package(pkg) => { diff --git a/src/cargo/diagnostics/rules/blanket_hint_mostly_unused.rs b/src/cargo/diagnostics/rules/blanket_hint_mostly_unused.rs index 83cab94311b..7534bcb6bca 100644 --- a/src/cargo/diagnostics/rules/blanket_hint_mostly_unused.rs +++ b/src/cargo/diagnostics/rules/blanket_hint_mostly_unused.rs @@ -61,7 +61,7 @@ pub(crate) fn lint_workspace( maybe_pkg: &MaybePackage, path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { diff --git a/src/cargo/diagnostics/rules/deferred_parse_diagnostics.rs b/src/cargo/diagnostics/rules/deferred_parse_diagnostics.rs index 07f4c2093ae..55d39011f15 100644 --- a/src/cargo/diagnostics/rules/deferred_parse_diagnostics.rs +++ b/src/cargo/diagnostics/rules/deferred_parse_diagnostics.rs @@ -13,7 +13,7 @@ use crate::diagnostics::rel_cwd_manifest_path; pub(crate) fn diagnose_manifest( manifest: ManifestFor<'_>, manifest_path: &Path, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let warnings = match &manifest { diff --git a/src/cargo/diagnostics/rules/im_a_teapot.rs b/src/cargo/diagnostics/rules/im_a_teapot.rs index 1326b48a395..b5d8542caa2 100644 --- a/src/cargo/diagnostics/rules/im_a_teapot.rs +++ b/src/cargo/diagnostics/rules/im_a_teapot.rs @@ -35,7 +35,7 @@ pub(crate) fn lint_package( pkg: &Package, path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let manifest = pkg.manifest(); diff --git a/src/cargo/diagnostics/rules/implicit_minimum_version_req.rs b/src/cargo/diagnostics/rules/implicit_minimum_version_req.rs index 0c87c2e3cb3..3299467be48 100644 --- a/src/cargo/diagnostics/rules/implicit_minimum_version_req.rs +++ b/src/cargo/diagnostics/rules/implicit_minimum_version_req.rs @@ -90,7 +90,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -151,7 +151,7 @@ pub(crate) fn lint_workspace( maybe_pkg: &MaybePackage, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { diff --git a/src/cargo/diagnostics/rules/missing_lints_features.rs b/src/cargo/diagnostics/rules/missing_lints_features.rs index e437caf849c..28257ed2046 100644 --- a/src/cargo/diagnostics/rules/missing_lints_features.rs +++ b/src/cargo/diagnostics/rules/missing_lints_features.rs @@ -21,7 +21,7 @@ use crate::diagnostics::rel_cwd_manifest_path; pub(crate) fn diagnose_manifest( manifest: ManifestFor<'_>, manifest_path: &Path, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let normalized_toml = match &manifest { @@ -64,7 +64,7 @@ fn diagnose_manifest_inner( manifest: &ManifestFor<'_>, manifest_path: &Path, cargo_lints: &manifest::TomlToolLints, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let manifest_path = rel_cwd_manifest_path(manifest_path, gctx); @@ -104,7 +104,7 @@ fn report_feature_not_enabled( feature_gate: &Feature, manifest: &ManifestFor<'_>, manifest_path: &str, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let dash_feature_name = feature_gate.name().replace("_", "-"); diff --git a/src/cargo/diagnostics/rules/missing_lints_inheritance.rs b/src/cargo/diagnostics/rules/missing_lints_inheritance.rs index 85720909d76..a173db6c12f 100644 --- a/src/cargo/diagnostics/rules/missing_lints_inheritance.rs +++ b/src/cargo/diagnostics/rules/missing_lints_inheritance.rs @@ -59,7 +59,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { diff --git a/src/cargo/diagnostics/rules/non_kebab_case_bins.rs b/src/cargo/diagnostics/rules/non_kebab_case_bins.rs index e0d4af5d57a..57a9907511e 100644 --- a/src/cargo/diagnostics/rules/non_kebab_case_bins.rs +++ b/src/cargo/diagnostics/rules/non_kebab_case_bins.rs @@ -69,7 +69,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -88,7 +88,7 @@ fn lint_package_inner( manifest_path: &str, lint_level: LintLevel, source: LintLevelSource, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let manifest = pkg.manifest(); diff --git a/src/cargo/diagnostics/rules/non_kebab_case_features.rs b/src/cargo/diagnostics/rules/non_kebab_case_features.rs index d121db72661..c697467b71b 100644 --- a/src/cargo/diagnostics/rules/non_kebab_case_features.rs +++ b/src/cargo/diagnostics/rules/non_kebab_case_features.rs @@ -64,7 +64,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -82,7 +82,7 @@ fn lint_package_inner( manifest_path: &str, lint_level: LintLevel, source: LintLevelSource, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { for original_name in pkg.summary().features().keys() { diff --git a/src/cargo/diagnostics/rules/non_kebab_case_packages.rs b/src/cargo/diagnostics/rules/non_kebab_case_packages.rs index 0d5500baccc..a64fb05d044 100644 --- a/src/cargo/diagnostics/rules/non_kebab_case_packages.rs +++ b/src/cargo/diagnostics/rules/non_kebab_case_packages.rs @@ -64,7 +64,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -82,7 +82,7 @@ fn lint_package_inner( manifest_path: &str, lint_level: LintLevel, source: LintLevelSource, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let manifest = pkg.manifest(); diff --git a/src/cargo/diagnostics/rules/non_snake_case_features.rs b/src/cargo/diagnostics/rules/non_snake_case_features.rs index fd8955120ad..d8f83c73302 100644 --- a/src/cargo/diagnostics/rules/non_snake_case_features.rs +++ b/src/cargo/diagnostics/rules/non_snake_case_features.rs @@ -64,7 +64,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -82,7 +82,7 @@ fn lint_package_inner( manifest_path: &str, lint_level: LintLevel, source: LintLevelSource, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { for original_name in pkg.summary().features().keys() { diff --git a/src/cargo/diagnostics/rules/non_snake_case_packages.rs b/src/cargo/diagnostics/rules/non_snake_case_packages.rs index faaf48a5d94..b7f0f58df69 100644 --- a/src/cargo/diagnostics/rules/non_snake_case_packages.rs +++ b/src/cargo/diagnostics/rules/non_snake_case_packages.rs @@ -64,7 +64,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -82,7 +82,7 @@ fn lint_package_inner( manifest_path: &str, lint_level: LintLevel, source: LintLevelSource, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let manifest = pkg.manifest(); diff --git a/src/cargo/diagnostics/rules/redundant_homepage.rs b/src/cargo/diagnostics/rules/redundant_homepage.rs index 7a698cc6ff3..f2d834e7ab8 100644 --- a/src/cargo/diagnostics/rules/redundant_homepage.rs +++ b/src/cargo/diagnostics/rules/redundant_homepage.rs @@ -68,7 +68,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -86,7 +86,7 @@ fn lint_package_inner( manifest_path: &str, lint_level: LintLevel, source: LintLevelSource, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let manifest = pkg.manifest(); diff --git a/src/cargo/diagnostics/rules/redundant_readme.rs b/src/cargo/diagnostics/rules/redundant_readme.rs index 57fc14fcf47..0dd2a1f2b54 100644 --- a/src/cargo/diagnostics/rules/redundant_readme.rs +++ b/src/cargo/diagnostics/rules/redundant_readme.rs @@ -70,7 +70,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -88,7 +88,7 @@ fn lint_package_inner( manifest_path: &str, lint_level: LintLevel, source: LintLevelSource, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let manifest = pkg.manifest(); diff --git a/src/cargo/diagnostics/rules/text_direction_codepoint_in_comment.rs b/src/cargo/diagnostics/rules/text_direction_codepoint_in_comment.rs index 70805ca0713..a937b8cd7d1 100644 --- a/src/cargo/diagnostics/rules/text_direction_codepoint_in_comment.rs +++ b/src/cargo/diagnostics/rules/text_direction_codepoint_in_comment.rs @@ -51,7 +51,7 @@ pub(crate) fn lint_manifest( manifest: ManifestFor<'_>, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { diff --git a/src/cargo/diagnostics/rules/text_direction_codepoint_in_literal.rs b/src/cargo/diagnostics/rules/text_direction_codepoint_in_literal.rs index c7e8ace3486..62967bae365 100644 --- a/src/cargo/diagnostics/rules/text_direction_codepoint_in_literal.rs +++ b/src/cargo/diagnostics/rules/text_direction_codepoint_in_literal.rs @@ -52,7 +52,7 @@ pub(crate) fn lint_manifest( manifest: ManifestFor<'_>, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { diff --git a/src/cargo/diagnostics/rules/unknown_lints.rs b/src/cargo/diagnostics/rules/unknown_lints.rs index b342e45a4df..50157e3adf5 100644 --- a/src/cargo/diagnostics/rules/unknown_lints.rs +++ b/src/cargo/diagnostics/rules/unknown_lints.rs @@ -53,7 +53,7 @@ pub(crate) fn lint_manifest( manifest: ManifestFor<'_>, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let normalized_toml = match &manifest { @@ -111,7 +111,7 @@ fn lint_manifest_inner( manifest_path: &Path, level: &LintLevelProduct, cargo_lints: &TomlToolLints, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { diff --git a/src/cargo/diagnostics/rules/unused_dependencies.rs b/src/cargo/diagnostics/rules/unused_dependencies.rs index 8efb5cbac27..e10eeb5d64f 100644 --- a/src/cargo/diagnostics/rules/unused_dependencies.rs +++ b/src/cargo/diagnostics/rules/unused_dependencies.rs @@ -23,6 +23,7 @@ use crate::core::compiler::Unit; use crate::core::compiler::unused_deps::DependenciesState; use crate::core::compiler::unused_deps::UnusedDepState; use crate::core::dependency::DepKind; +use crate::diagnostics::GlobalDiagnosticStats; use crate::diagnostics::Lint; use crate::diagnostics::LintLevel; use crate::diagnostics::LintLevelProduct; @@ -99,7 +100,7 @@ pub(crate) fn lint_package( pkg: &Package, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { @@ -172,7 +173,7 @@ pub(crate) fn lint_package( #[instrument(skip_all)] pub fn lint_build_results( build_runner: &BuildRunner<'_, '_>, - global_stats: &mut ScopedDiagnosticStats, + global_stats: &mut GlobalDiagnosticStats, ) -> CargoResult<()> { for (pkg_id, states) in &build_runner.unused_dep_state.states { let Some(pkg) = get_package(&build_runner.unused_dep_state, pkg_id) else { @@ -207,7 +208,7 @@ pub fn lint_build_results( continue; } - let mut pkg_stats = ScopedDiagnosticStats::new(); + let mut pkg_stats = global_stats.scope(); lint_package_build_results(build_runner, pkg, states, level, &mut pkg_stats)?; // HACK: as other rules are added to this pass, this needs to move up into the pass if let Err(error) = @@ -215,7 +216,6 @@ pub fn lint_build_results( { build_runner.bcx.gctx.shell().error(error)?; } - *global_stats += pkg_stats; } Ok(()) } @@ -225,7 +225,7 @@ fn lint_package_build_results( pkg: &Package, states: &IndexMap, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, ) -> CargoResult<()> { let mut lint_count = 0; let LintLevelProduct { diff --git a/src/cargo/diagnostics/rules/unused_workspace_dependencies.rs b/src/cargo/diagnostics/rules/unused_workspace_dependencies.rs index d924d4e2ab9..579ec45f8ff 100644 --- a/src/cargo/diagnostics/rules/unused_workspace_dependencies.rs +++ b/src/cargo/diagnostics/rules/unused_workspace_dependencies.rs @@ -52,7 +52,7 @@ pub(crate) fn lint_workspace( maybe_pkg: &MaybePackage, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { diff --git a/src/cargo/diagnostics/rules/unused_workspace_package_fields.rs b/src/cargo/diagnostics/rules/unused_workspace_package_fields.rs index 7ecc2fb0e12..f85015ac94f 100644 --- a/src/cargo/diagnostics/rules/unused_workspace_package_fields.rs +++ b/src/cargo/diagnostics/rules/unused_workspace_package_fields.rs @@ -52,7 +52,7 @@ pub(crate) fn lint_workspace( maybe_pkg: &MaybePackage, manifest_path: &Path, level: LintLevelProduct, - pkg_stats: &mut ScopedDiagnosticStats, + pkg_stats: &mut ScopedDiagnosticStats<'_>, gctx: &GlobalContext, ) -> CargoResult<()> { let LintLevelProduct { From 2a06b573f86a380747ca6abf1a432bf547f84797 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 11 Jun 2026 15:15:19 -0500 Subject: [PATCH 3/3] fix(diag): Report all errors, in order This makes the two existing passes more consistent. The downside is that if there is an error, that might not be the final message. This is the case with `--keep-going` (see https://rust-lang.zulipchat.com/#narrow/channel/246057-t-cargo/topic/.60--keep-going.60.20and.20compilation.20errors/near/595741468). We may want to iterate on this further and make stop after the current manifest/package unless `--keep-going` is provided. --- src/cargo/diagnostics/mod.rs | 18 +++++++++++++++--- src/cargo/diagnostics/passes.rs | 17 +++-------------- .../diagnostics/rules/unused_dependencies.rs | 7 +------ tests/testsuite/lints/mod.rs | 2 +- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/cargo/diagnostics/mod.rs b/src/cargo/diagnostics/mod.rs index 4c636ee4c21..3840b4bde95 100644 --- a/src/cargo/diagnostics/mod.rs +++ b/src/cargo/diagnostics/mod.rs @@ -53,7 +53,6 @@ //! //! [future-incompat lint]: https://rustc-dev-guide.rust-lang.org/diagnostics.html#future-incompatible-lints -use anyhow::bail; use cargo_util_schemas::manifest::RustVersion; use cargo_util_schemas::manifest::TomlToolLints; @@ -93,6 +92,16 @@ impl GlobalDiagnosticStats { pub fn error_count(&self) -> usize { self.error_count } + + pub fn ok(&self) -> CargoResult<()> { + if 0 < self.error_count { + Err(crate::Error::new(crate::AlreadyPrintedError::new( + anyhow::format_err!("see above"), + ))) + } else { + Ok(()) + } + } } pub struct ScopedDiagnosticStats<'g> { @@ -137,6 +146,9 @@ impl ScopedDiagnosticStats<'_> { } } + /// Print a summary to the user + /// + /// **Note:** be sure to call `GlobalDiagnosticStats::ok` or equivalent to fail the operation pub fn report_summary( &self, action: &str, @@ -159,10 +171,10 @@ impl ScopedDiagnosticStats<'_> { let name = name .map(|n| format!("`{n}`")) .unwrap_or_else(|| "workspace".to_owned()); - bail!( + gctx.shell().error(format!( "could not {action} {name} (manifest) due to {} previous error{plural}", self.error_count - ) + ))?; } Ok(()) diff --git a/src/cargo/diagnostics/passes.rs b/src/cargo/diagnostics/passes.rs index 369a9445568..13f93c63ef9 100644 --- a/src/cargo/diagnostics/passes.rs +++ b/src/cargo/diagnostics/passes.rs @@ -89,28 +89,17 @@ pub fn emit_parse_diagnostics( rules: &[ParsePassRule<'_>], ) -> CargoResult<()> { let mut stats = GlobalDiagnosticStats::new(); - let mut first_emitted_error = None; - if let Err(e) = emit_parse_ws_diagnostics(workspace, rules, &mut stats) { - first_emitted_error = Some(e); - } + emit_parse_ws_diagnostics(workspace, rules, &mut stats)?; for maybe_pkg in workspace.loaded_maybe() { if let MaybePackage::Package(pkg) = maybe_pkg { let path = pkg.manifest_path(); - if let Err(e) = emit_parse_pkg_diagnostics(workspace, pkg, &path, rules, &mut stats) - && first_emitted_error.is_none() - { - first_emitted_error = Some(e); - } + emit_parse_pkg_diagnostics(workspace, pkg, &path, rules, &mut stats)?; } } - if let Some(error) = first_emitted_error { - Err(error) - } else { - Ok(()) - } + stats.ok() } fn emit_parse_pkg_diagnostics( diff --git a/src/cargo/diagnostics/rules/unused_dependencies.rs b/src/cargo/diagnostics/rules/unused_dependencies.rs index e10eeb5d64f..b6b36405e0c 100644 --- a/src/cargo/diagnostics/rules/unused_dependencies.rs +++ b/src/cargo/diagnostics/rules/unused_dependencies.rs @@ -210,12 +210,7 @@ pub fn lint_build_results( let mut pkg_stats = global_stats.scope(); lint_package_build_results(build_runner, pkg, states, level, &mut pkg_stats)?; - // HACK: as other rules are added to this pass, this needs to move up into the pass - if let Err(error) = - pkg_stats.report_summary("finalize", Some(&*pkg.name()), build_runner.bcx.gctx) - { - build_runner.bcx.gctx.shell().error(error)?; - } + pkg_stats.report_summary("finalize", Some(&*pkg.name()), build_runner.bcx.gctx)?; } Ok(()) } diff --git a/tests/testsuite/lints/mod.rs b/tests/testsuite/lints/mod.rs index ac31971c995..3f6ea250da7 100644 --- a/tests/testsuite/lints/mod.rs +++ b/tests/testsuite/lints/mod.rs @@ -385,6 +385,7 @@ authors = [] | ^^^^^^^^^^^^^^^^^^^ this is behind `test-dummy-unstable`, which is not enabled | = [HELP] consider adding `cargo-features = ["test-dummy-unstable"]` to the top of the manifest +[ERROR] could not parse workspace (manifest) due to 2 previous errors [WARNING] missing `[lints]` to inherit `[workspace.lints]` --> foo/Cargo.toml = [NOTE] `cargo::missing_lints_inheritance` is set to `warn` by default @@ -400,7 +401,6 @@ authors = [] 8 + [lints] | [WARNING] `foo` (manifest) generated 1 warning -[ERROR] could not parse workspace (manifest) due to 2 previous errors "#]]) .run();