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
1 change: 1 addition & 0 deletions src/cargo/core/compiler/job_queue/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,7 @@ impl<'gctx> DrainState<'gctx> {
&mut global_stats,
));
errors.count += global_stats.error_count();
build_runner.compilation.lint_warning_count += global_stats.lint_warning_count();
}

let profile_name = build_runner.bcx.build_config.requested_profile;
Expand Down
35 changes: 28 additions & 7 deletions src/cargo/diagnostics/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use cargo_util_schemas::manifest;
use cargo_util_terminal::report::Level;

use crate::core::{Feature, Features};
use crate::util::GlobalContext;
use crate::util::context::WarningHandling;

#[derive(Clone, Debug)]
pub struct Lint {
Expand All @@ -30,6 +32,7 @@ impl Lint {
pkg_lints: &manifest::TomlToolLints,
pkg_rust_version: Option<&manifest::RustVersion>,
unstable_features: &Features,
gctx: &GlobalContext,
) -> LintLevelProduct {
// We should return `Allow` if a lint is behind a feature, but it is
// not enabled, that way the lint does not run.
Expand Down Expand Up @@ -83,6 +86,15 @@ impl Lint {
)
})
.unwrap();

let (level, source) = match (level, gctx.warning_handling().ok()) {
// `Deny` needs to be handled later, at the end of the operation
(LintLevel::Warn, Some(WarningHandling::Allow)) => {
(LintLevel::Allow, LintLevelSource::Default)
}
_ => (level, source),
};

LintLevelProduct { level, source }
}

Expand Down Expand Up @@ -215,6 +227,15 @@ mod tests {
hidden: false,
};

fn gctx() -> GlobalContext {
let cwd = std::env::current_dir().unwrap();
GlobalContext::new(
cargo_util_terminal::Shell::new(),
cwd.clone(),
home::cargo_home_with_cwd(&cwd).unwrap(),
)
}

fn test_lint(name: &'static str, group: &'static LintGroup) -> Lint {
Lint {
name,
Expand All @@ -237,7 +258,7 @@ mod tests {
);
let features = Features::default();

let LintLevelProduct { level, source } = lint.level(&pkg_lints, None, &features);
let LintLevelProduct { level, source } = lint.level(&pkg_lints, None, &features, &gctx());
assert_eq!(level, LintLevel::Deny);
assert_eq!(source, LintLevelSource::Package);
}
Expand All @@ -253,7 +274,7 @@ mod tests {
);
let features = Features::default();

let LintLevelProduct { level, source } = lint.level(&pkg_lints, None, &features);
let LintLevelProduct { level, source } = lint.level(&pkg_lints, None, &features, &gctx());
assert_eq!(level, LintLevel::Deny);
assert_eq!(source, LintLevelSource::Package);
}
Expand All @@ -269,7 +290,7 @@ mod tests {
);
let features = Features::default();

let LintLevelProduct { level, source } = lint.level(&pkg_lints, None, &features);
let LintLevelProduct { level, source } = lint.level(&pkg_lints, None, &features, &gctx());
assert_eq!(level, LintLevel::Deny);
assert_eq!(source, LintLevelSource::Package);
}
Expand All @@ -289,7 +310,7 @@ mod tests {
);
let features = Features::default();

let LintLevelProduct { level, source } = lint.level(&pkg_lints, None, &features);
let LintLevelProduct { level, source } = lint.level(&pkg_lints, None, &features, &gctx());
assert_eq!(level, LintLevel::Deny);
assert_eq!(source, LintLevelSource::Package);
}
Expand All @@ -309,7 +330,7 @@ mod tests {
);
let features = Features::default();

let LintLevelProduct { level, source } = lint.level(&pkg_lints, None, &features);
let LintLevelProduct { level, source } = lint.level(&pkg_lints, None, &features, &gctx());
assert_eq!(level, LintLevel::Deny);
assert_eq!(source, LintLevelSource::Package);
}
Expand Down Expand Up @@ -337,7 +358,7 @@ mod tests {
);
let features = Features::default();

let LintLevelProduct { level, source } = lint.level(&pkg_lints, None, &features);
let LintLevelProduct { level, source } = lint.level(&pkg_lints, None, &features, &gctx());
assert_eq!(level, LintLevel::Deny);
assert_eq!(source, LintLevelSource::Package);
}
Expand Down Expand Up @@ -365,7 +386,7 @@ mod tests {
);
let features = Features::default();

let LintLevelProduct { level, source } = lint.level(&pkg_lints, None, &features);
let LintLevelProduct { level, source } = lint.level(&pkg_lints, None, &features, &gctx());
assert_eq!(level, LintLevel::Allow);
assert_eq!(source, LintLevelSource::Package);
}
Expand Down
42 changes: 30 additions & 12 deletions src/cargo/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,26 @@ pub use lint::{Lint, LintGroup, LintLevel, LintLevelProduct, LintLevelSource};
pub use report::{AsIndex, cwd_rel_path, get_key_value, get_key_value_span, workspace_rel_path};
pub use rules::{LINT_GROUPS, LINTS};

pub struct PassOutput {
pub lint_warning_count: usize,
}

pub struct GlobalDiagnosticStats {
error_count: usize,
lint_warning_count: usize,
}

impl GlobalDiagnosticStats {
pub fn new() -> Self {
Self { error_count: 0 }
Self {
error_count: 0,
lint_warning_count: 0,
}
}

pub fn scope(&mut self) -> ScopedDiagnosticStats<'_> {
ScopedDiagnosticStats {
warning_count: 0,
lint_warning_count: 0,
error_count: 0,
global: self,
}
Expand All @@ -94,29 +101,30 @@ impl GlobalDiagnosticStats {
self.error_count
}

pub fn ok(&self) -> CargoResult<()> {
pub fn lint_warning_count(&self) -> usize {
self.lint_warning_count
}

pub fn ok(&self) -> CargoResult<PassOutput> {
if 0 < self.error_count {
Err(crate::Error::new(crate::AlreadyPrintedError::new(
anyhow::format_err!("see above"),
)))
} else {
Ok(())
Ok(PassOutput {
lint_warning_count: self.lint_warning_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
}

pub fn warning_count(&self) -> usize {
self.warning_count
}
Expand All @@ -140,7 +148,7 @@ impl ScopedDiagnosticStats<'_> {
self.record_error();
}
LintLevel::Warn => {
self.lint_warning_count += 1;
self.global.lint_warning_count += 1;
self.record_warning();
}
LintLevel::Allow => {}
Expand Down Expand Up @@ -194,8 +202,18 @@ pub enum ManifestFor<'a> {
}

impl ManifestFor<'_> {
fn lint_level(&self, pkg_lints: &TomlToolLints, lint: &Lint) -> LintLevelProduct {
lint.level(pkg_lints, self.rust_version(), self.unstable_features())
fn lint_level(
&self,
pkg_lints: &TomlToolLints,
lint: &Lint,
gctx: &GlobalContext,
) -> LintLevelProduct {
lint.level(
pkg_lints,
self.rust_version(),
self.unstable_features(),
gctx,
)
}

pub fn rust_version(&self) -> Option<&RustVersion> {
Expand Down
9 changes: 6 additions & 3 deletions src/cargo/diagnostics/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::diagnostics::Lint;
use crate::diagnostics::LintLevel;
use crate::diagnostics::LintLevelProduct;
use crate::diagnostics::ManifestFor;
use crate::diagnostics::PassOutput;
use crate::diagnostics::ScopedDiagnosticStats;

#[derive(Clone)]
Expand Down Expand Up @@ -93,7 +94,7 @@ type FnLintPackage = fn(
pub fn emit_parse_diagnostics(
workspace: &Workspace<'_>,
rules: &[ParsePassRule<'_>],
) -> CargoResult<()> {
) -> CargoResult<PassOutput> {
let mut stats = GlobalDiagnosticStats::new();

if is_local_workspace(workspace) {
Expand Down Expand Up @@ -154,7 +155,7 @@ fn emit_parse_pkg_diagnostics(
ParsePassRule::LintManifest { rule, lint } => {
if workspace.gctx().cli_unstable().cargo_lints {
let manifest: ManifestFor<'_> = pkg.into();
let level = manifest.lint_level(&cargo_lints, lint);
let level = manifest.lint_level(&cargo_lints, lint, workspace.gctx());
if level.level != LintLevel::Allow {
rule(
workspace,
Expand All @@ -177,6 +178,7 @@ fn emit_parse_pkg_diagnostics(
&cargo_lints,
pkg.rust_version(),
pkg.manifest().unstable_features(),
workspace.gctx(),
);

if level.level != LintLevel::Allow {
Expand Down Expand Up @@ -242,7 +244,7 @@ fn emit_parse_ws_diagnostics(
ParsePassRule::LintManifest { rule, lint } => {
if workspace.gctx().cli_unstable().cargo_lints {
let manifest: ManifestFor<'_> = (workspace, workspace.root_maybe()).into();
let level = manifest.lint_level(&cargo_lints, lint);
let level = manifest.lint_level(&cargo_lints, lint, workspace.gctx());
if level.level != LintLevel::Allow {
rule(
workspace,
Expand Down Expand Up @@ -270,6 +272,7 @@ fn emit_parse_ws_diagnostics(
&cargo_lints,
workspace.lowest_rust_version(),
workspace.root_maybe().unstable_features(),
workspace.gctx(),
);
if level.level != LintLevel::Allow {
rule(
Expand Down
1 change: 1 addition & 0 deletions src/cargo/diagnostics/rules/unused_dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ pub fn lint_build_results(
&cargo_lints,
pkg.rust_version(),
pkg.manifest().unstable_features(),
build_runner.bcx.gctx,
);
if !pkg_id.source_id().is_path() {
for (dep_kind, state) in states.iter() {
Expand Down
5 changes: 3 additions & 2 deletions src/cargo/ops/cargo_compile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,13 @@ pub fn compile_with_exec<'a>(
options: &CompileOptions,
exec: &Arc<dyn Executor>,
) -> CargoResult<Compilation<'a>> {
crate::diagnostics::passes::emit_parse_diagnostics(
let parse_pass_output = crate::diagnostics::passes::emit_parse_diagnostics(
ws,
crate::diagnostics::rules::PARSE_PASS_RULES,
)?;
let compilation = compile_ws(ws, options, exec)?;
if ws.gctx().warning_handling()? == WarningHandling::Deny && compilation.lint_warning_count > 0
if ws.gctx().warning_handling()? == WarningHandling::Deny
&& (compilation.lint_warning_count + parse_pass_output.lint_warning_count) > 0
{
anyhow::bail!("warnings are denied by `build.warnings` configuration")
}
Expand Down
9 changes: 8 additions & 1 deletion src/cargo/ops/cargo_fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::ops;
use crate::util::CargoResult;
use crate::util::GlobalContext;
use crate::util::context::JobsConfig;
use crate::util::context::WarningHandling;
use std::collections::HashSet;

pub struct FetchOptions<'a> {
Expand All @@ -20,7 +21,7 @@ pub fn fetch<'a>(
ws: &Workspace<'a>,
options: &FetchOptions<'a>,
) -> CargoResult<(Resolve, PackageSet<'a>)> {
crate::diagnostics::passes::emit_parse_diagnostics(
let parse_pass_output = crate::diagnostics::passes::emit_parse_diagnostics(
ws,
crate::diagnostics::rules::PARSE_PASS_RULES,
)?;
Expand Down Expand Up @@ -83,5 +84,11 @@ pub fn fetch<'a>(
packages.get_many(to_download)?;
crate::core::gc::auto_gc(gctx);

if ws.gctx().warning_handling()? == WarningHandling::Deny
Comment thread
epage marked this conversation as resolved.
&& parse_pass_output.lint_warning_count > 0
{
anyhow::bail!("warnings are denied by `build.warnings` configuration")
}

Ok((resolve, packages))
}
Loading
Loading