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
4 changes: 2 additions & 2 deletions src/cargo/core/compiler/job_queue/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::GlobalDiagnosticStats;
use crate::diagnostics::rules::unused_dependencies;
use crate::util::CargoResult;
use crate::util::context::WarningHandling;
Expand Down Expand Up @@ -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 = GlobalDiagnosticStats::new();
drop(unused_dependencies::lint_build_results(
build_runner,
&mut global_stats,
Expand Down
69 changes: 38 additions & 31 deletions src/cargo/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;

Expand All @@ -72,21 +71,47 @@ 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 {
warning_count: usize,
lint_warning_count: usize,
pub struct GlobalDiagnosticStats {
error_count: usize,
}

impl DiagnosticStats {
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 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> {
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
}
Expand All @@ -105,6 +130,7 @@ impl DiagnosticStats {

pub fn record_error(&mut self) {
self.error_count += 1;
self.global.error_count += 1;
}

pub fn record_lint(&mut self, lint: LintLevel) {
Expand All @@ -120,6 +146,9 @@ impl DiagnosticStats {
}
}

/// 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,
Expand All @@ -142,38 +171,16 @@ impl DiagnosticStats {
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(())
}
}

impl std::ops::Add for DiagnosticStats {
type Output = DiagnosticStats;

fn add(mut self, rhs: Self) -> Self::Output {
self += rhs;
self
}
}

impl std::ops::AddAssign for DiagnosticStats {
fn add_assign(&mut self, rhs: Self) {
let DiagnosticStats {
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.
Expand Down
46 changes: 22 additions & 24 deletions src/cargo/diagnostics/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ use crate::GlobalContext;
use crate::core::MaybePackage;
use crate::core::Package;
use crate::core::Workspace;
use crate::diagnostics::DiagnosticStats;
use crate::diagnostics::GlobalDiagnosticStats;
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> {
Expand Down Expand Up @@ -39,24 +40,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<()>;

Expand All @@ -65,7 +71,7 @@ type FnLintWorkspace = fn(
&MaybePackage,
&Path,
LintLevelProduct,
&mut DiagnosticStats,
&mut ScopedDiagnosticStats<'_>,
&GlobalContext,
) -> CargoResult<()>;

Expand All @@ -74,45 +80,36 @@ type FnLintPackage = fn(
&Package,
&Path,
LintLevelProduct,
&mut DiagnosticStats,
&mut ScopedDiagnosticStats<'_>,
&GlobalContext,
) -> CargoResult<()>;

pub fn emit_parse_diagnostics(
workspace: &Workspace<'_>,
rules: &[ParsePassRule<'_>],
) -> CargoResult<()> {
let mut first_emitted_error = None;
let mut stats = GlobalDiagnosticStats::new();

if let Err(e) = emit_parse_ws_diagnostics(workspace, rules) {
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)
&& 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(
workspace: &Workspace<'_>,
pkg: &Package,
path: &Path,
rules: &[ParsePassRule<'_>],
global_stats: &mut GlobalDiagnosticStats,
) -> CargoResult<()> {
let mut pkg_stats = DiagnosticStats::new();
let mut pkg_stats = global_stats.scope();

let toml_lints = pkg
.manifest()
Expand Down Expand Up @@ -176,8 +173,9 @@ fn emit_parse_pkg_diagnostics(
fn emit_parse_ws_diagnostics(
workspace: &Workspace<'_>,
rules: &[ParsePassRule<'_>],
global_stats: &mut GlobalDiagnosticStats,
) -> CargoResult<()> {
let mut pkg_stats = DiagnosticStats::new();
let mut pkg_stats = global_stats.scope();

let cargo_lints = match workspace.root_maybe() {
MaybePackage::Package(pkg) => {
Expand Down
4 changes: 2 additions & 2 deletions src/cargo/diagnostics/rules/blanket_hint_mostly_unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions src/cargo/diagnostics/rules/deferred_parse_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions src/cargo/diagnostics/rules/im_a_teapot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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();
Expand Down
6 changes: 3 additions & 3 deletions src/cargo/diagnostics/rules/implicit_minimum_version_req.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
8 changes: 4 additions & 4 deletions src/cargo/diagnostics/rules/missing_lints_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ 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;

#[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 normalized_toml = match &manifest {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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("_", "-");
Expand Down
Loading