Skip to content

Commit 2274a1a

Browse files
committed
feat: add build.warnings config option to control rustc warnings
1 parent d869944 commit 2274a1a

File tree

9 files changed

+137
-32
lines changed

9 files changed

+137
-32
lines changed

src/cargo/core/compiler/compilation.rs

+4
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ pub struct Compilation<'gctx> {
122122
target_runners: HashMap<CompileKind, Option<(PathBuf, Vec<String>)>>,
123123
/// The linker to use for each host or target.
124124
target_linkers: HashMap<CompileKind, Option<PathBuf>>,
125+
126+
/// The total number of warnings emitted by the compilation.
127+
pub warning_count: usize,
125128
}
126129

127130
impl<'gctx> Compilation<'gctx> {
@@ -169,6 +172,7 @@ impl<'gctx> Compilation<'gctx> {
169172
.chain(Some(&CompileKind::Host))
170173
.map(|kind| Ok((*kind, target_linker(bcx, *kind)?)))
171174
.collect::<CargoResult<HashMap<_, _>>>()?,
175+
warning_count: 0,
172176
})
173177
}
174178

src/cargo/core/compiler/job_queue/mod.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ use crate::core::compiler::future_incompat::{
141141
};
142142
use crate::core::resolver::ResolveBehavior;
143143
use crate::core::{PackageId, Shell, TargetKind};
144+
use crate::util::context::WarningHandling;
144145
use crate::util::diagnostic_server::{self, DiagnosticPrinter};
145146
use crate::util::errors::AlreadyPrintedError;
146147
use crate::util::machine_message::{self, Message as _};
@@ -602,6 +603,7 @@ impl<'gctx> DrainState<'gctx> {
602603
plan: &mut BuildPlan,
603604
event: Message,
604605
) -> Result<(), ErrorToHandle> {
606+
let warning_handling = build_runner.bcx.gctx.warning_handling()?;
605607
match event {
606608
Message::Run(id, cmd) => {
607609
build_runner
@@ -639,7 +641,9 @@ impl<'gctx> DrainState<'gctx> {
639641
}
640642
}
641643
Message::Warning { id, warning } => {
642-
build_runner.bcx.gctx.shell().warn(warning)?;
644+
if warning_handling != WarningHandling::Allow {
645+
build_runner.bcx.gctx.shell().warn(warning)?;
646+
}
643647
self.bump_warning_count(id, true, false);
644648
}
645649
Message::WarningCount {
@@ -660,7 +664,7 @@ impl<'gctx> DrainState<'gctx> {
660664
trace!("end: {:?}", id);
661665
self.finished += 1;
662666
self.report_warning_count(
663-
build_runner.bcx.gctx,
667+
build_runner,
664668
id,
665669
&build_runner.bcx.rustc().workspace_wrapper,
666670
);
@@ -1024,17 +1028,19 @@ impl<'gctx> DrainState<'gctx> {
10241028
/// Displays a final report of the warnings emitted by a particular job.
10251029
fn report_warning_count(
10261030
&mut self,
1027-
gctx: &GlobalContext,
1031+
runner: &mut BuildRunner<'_, '_>,
10281032
id: JobId,
10291033
rustc_workspace_wrapper: &Option<PathBuf>,
10301034
) {
1031-
let count = match self.warning_count.remove(&id) {
1035+
let gctx = runner.bcx.gctx;
1036+
let count = match self.warning_count.get(&id) {
10321037
// An error could add an entry for a `Unit`
10331038
// with 0 warnings but having fixable
10341039
// warnings be disallowed
10351040
Some(count) if count.total > 0 => count,
10361041
None | Some(_) => return,
10371042
};
1043+
runner.compilation.warning_count += count.total;
10381044
let unit = &self.active[&id];
10391045
let mut message = descriptive_pkg_name(&unit.pkg.name(), &unit.target, &unit.mode);
10401046
message.push_str(" generated ");

src/cargo/core/compiler/mod.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ pub use crate::core::compiler::unit::{Unit, UnitInterner};
9191
use crate::core::manifest::TargetSourcePath;
9292
use crate::core::profiles::{PanicStrategy, Profile, StripInner};
9393
use crate::core::{Feature, PackageId, Target, Verbosity};
94+
use crate::util::context::WarningHandling;
9495
use crate::util::errors::{CargoResult, VerboseError};
9596
use crate::util::interning::InternedString;
9697
use crate::util::machine_message::{self, Message};
@@ -202,13 +203,15 @@ fn compile<'gctx>(
202203
} else {
203204
// We always replay the output cache,
204205
// since it might contain future-incompat-report messages
206+
let show_diagnostics = unit.show_warnings(bcx.gctx)
207+
&& build_runner.bcx.gctx.warning_handling()? != WarningHandling::Allow;
205208
let work = replay_output_cache(
206209
unit.pkg.package_id(),
207210
PathBuf::from(unit.pkg.manifest_path()),
208211
&unit.target,
209212
build_runner.files().message_cache_path(unit),
210213
build_runner.bcx.build_config.message_format,
211-
unit.show_warnings(bcx.gctx),
214+
show_diagnostics,
212215
);
213216
// Need to link targets on both the dirty and fresh.
214217
work.then(link_targets(build_runner, unit, true)?)
@@ -1658,10 +1661,12 @@ impl OutputOptions {
16581661
// Remove old cache, ignore ENOENT, which is the common case.
16591662
drop(fs::remove_file(&path));
16601663
let cache_cell = Some((path, LazyCell::new()));
1664+
let show_diagnostics =
1665+
build_runner.bcx.gctx.warning_handling().unwrap_or_default() != WarningHandling::Allow;
16611666
OutputOptions {
16621667
format: build_runner.bcx.build_config.message_format,
16631668
cache_cell,
1664-
show_diagnostics: true,
1669+
show_diagnostics,
16651670
warnings_seen: 0,
16661671
errors_seen: 0,
16671672
}

src/cargo/core/features.rs

+2
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,7 @@ unstable_cli_options!(
793793
target_applies_to_host: bool = ("Enable the `target-applies-to-host` key in the .cargo/config.toml file"),
794794
trim_paths: bool = ("Enable the `trim-paths` option in profiles"),
795795
unstable_options: bool = ("Allow the usage of unstable options"),
796+
warnings: bool = ("Allow use of the build.warnings config key"),
796797
);
797798

798799
const STABILIZED_COMPILE_PROGRESS: &str = "The progress bar is now always \
@@ -1298,6 +1299,7 @@ impl CliUnstable {
12981299
"script" => self.script = parse_empty(k, v)?,
12991300
"target-applies-to-host" => self.target_applies_to_host = parse_empty(k, v)?,
13001301
"unstable-options" => self.unstable_options = parse_empty(k, v)?,
1302+
"warnings" => self.warnings = parse_empty(k, v)?,
13011303
_ => bail!("\
13021304
unknown `-Z` flag specified: {k}\n\n\
13031305
For available unstable features, see https://doc.rust-lang.org/nightly/cargo/reference/unstable.html\n\

src/cargo/ops/cargo_compile/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ use crate::core::{PackageId, PackageSet, SourceId, TargetKind, Workspace};
5252
use crate::drop_println;
5353
use crate::ops;
5454
use crate::ops::resolve::WorkspaceResolve;
55-
use crate::util::context::GlobalContext;
55+
use crate::util::context::{GlobalContext, WarningHandling};
5656
use crate::util::interning::InternedString;
5757
use crate::util::{CargoResult, StableHasher};
5858

@@ -138,7 +138,11 @@ pub fn compile_with_exec<'a>(
138138
exec: &Arc<dyn Executor>,
139139
) -> CargoResult<Compilation<'a>> {
140140
ws.emit_warnings()?;
141-
compile_ws(ws, options, exec)
141+
let compilation = compile_ws(ws, options, exec)?;
142+
if ws.gctx().warning_handling()? == WarningHandling::Deny && compilation.warning_count > 0 {
143+
anyhow::bail!("warnings are denied by `build.warnings` configuration")
144+
}
145+
Ok(compilation)
142146
}
143147

144148
/// Like [`compile_with_exec`] but without warnings from manifest parsing.

src/cargo/util/context/mod.rs

+23
Original file line numberDiff line numberDiff line change
@@ -2022,6 +2022,15 @@ impl GlobalContext {
20222022
})?;
20232023
Ok(deferred.borrow_mut())
20242024
}
2025+
2026+
/// Get the global [`WarningHandling`] configuration.
2027+
pub fn warning_handling(&self) -> CargoResult<WarningHandling> {
2028+
if self.unstable_flags.warnings {
2029+
Ok(self.build_config()?.warnings.unwrap_or_default())
2030+
} else {
2031+
Ok(WarningHandling::default())
2032+
}
2033+
}
20252034
}
20262035

20272036
/// Internal error for serde errors.
@@ -2633,6 +2642,20 @@ pub struct CargoBuildConfig {
26332642
// deprecated alias for artifact-dir
26342643
pub out_dir: Option<ConfigRelativePath>,
26352644
pub artifact_dir: Option<ConfigRelativePath>,
2645+
pub warnings: Option<WarningHandling>,
2646+
}
2647+
2648+
/// Whether warnings should warn, be allowed, or cause an error.
2649+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize, Default)]
2650+
#[serde(rename_all = "kebab-case")]
2651+
pub enum WarningHandling {
2652+
#[default]
2653+
/// Output warnings.
2654+
Warn,
2655+
/// Allow warnings (do not output them).
2656+
Allow,
2657+
/// Error if warnings are emitted.
2658+
Deny,
26362659
}
26372660

26382661
/// Configuration for `build.target`.

src/doc/src/reference/unstable.md

+20
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ Each new feature described below should explain how to use it.
120120
* [lockfile-path](#lockfile-path) --- Allows to specify a path to lockfile other than the default path `<workspace_root>/Cargo.lock`.
121121
* [package-workspace](#package-workspace) --- Allows for packaging and publishing multiple crates in a workspace.
122122
* [native-completions](#native-completions) --- Move cargo shell completions to native completions.
123+
* [warnings](#warnings) --- controls warning behavior; options for allowing or denying warnings.
123124

124125
## allow-features
125126

@@ -1991,3 +1992,22 @@ default behavior.
19911992

19921993
See the [build script documentation](build-scripts.md#rustc-check-cfg) for information
19931994
about specifying custom cfgs.
1995+
1996+
## warnings
1997+
1998+
The `-Z warnings` feature enables the `build.warnings` configuration option to control how
1999+
Cargo handles warnings. If the `-Z warnings` unstable flag is not enabled, then
2000+
the `build.warnings` config will be ignored.
2001+
2002+
This setting currently only applies to rustc warnings. It may apply to additional warnings (such as Cargo lints or Cargo warnings)
2003+
in the future.
2004+
2005+
### `build.warnings`
2006+
* Type: string
2007+
* Default: `warn`
2008+
* Environment: `CARGO_BUILD_WARNINGS`
2009+
2010+
Controls how Cargo handles warnings. Allowed values are:
2011+
* `warn`: warnings are emitted as warnings (default).
2012+
* `allow`: warnings are hidden.
2013+
* `deny`: if warnings are emitted, an error will be raised at the end of the operation and the process will exit with a failure exit code.

tests/testsuite/cargo/z_help/stdout.term.svg

+8-6
Loading

0 commit comments

Comments
 (0)