Skip to content

Commit c6bafa7

Browse files
committed
Add --json unused-externs-silent with original behaviour
Since Cargo wants to do its own fatal error handling for unused dependencies, add the option `--json unused-externs-silent` which has the original behaviour of not indicating non-zero exit status for `deny`/`forbid`-level unused dependencies.
1 parent 0529a13 commit c6bafa7

File tree

8 files changed

+65
-15
lines changed

8 files changed

+65
-15
lines changed

compiler/rustc_errors/src/lib.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -969,10 +969,15 @@ impl Handler {
969969
self.inner.borrow_mut().emitter.emit_future_breakage_report(diags)
970970
}
971971

972-
pub fn emit_unused_externs(&self, lint_level: rustc_lint_defs::Level, unused_externs: &[&str]) {
972+
pub fn emit_unused_externs(
973+
&self,
974+
lint_level: rustc_lint_defs::Level,
975+
loud: bool,
976+
unused_externs: &[&str],
977+
) {
973978
let mut inner = self.inner.borrow_mut();
974979

975-
if lint_level.is_error() {
980+
if loud && lint_level.is_error() {
976981
inner.bump_err_count();
977982
}
978983

compiler/rustc_metadata/src/creader.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,12 @@ impl CStore {
195195
}
196196

197197
pub fn report_unused_deps(&self, tcx: TyCtxt<'_>) {
198+
let json_unused_externs = tcx.sess.opts.json_unused_externs;
199+
198200
// We put the check for the option before the lint_level_at_node call
199201
// because the call mutates internal state and introducing it
200202
// leads to some ui tests failing.
201-
if !tcx.sess.opts.json_unused_externs {
203+
if !json_unused_externs.is_enabled() {
202204
return;
203205
}
204206
let level = tcx
@@ -208,7 +210,11 @@ impl CStore {
208210
let unused_externs =
209211
self.unused_externs.iter().map(|ident| ident.to_ident_string()).collect::<Vec<_>>();
210212
let unused_externs = unused_externs.iter().map(String::as_str).collect::<Vec<&str>>();
211-
tcx.sess.parse_sess.span_diagnostic.emit_unused_externs(level, &unused_externs);
213+
tcx.sess.parse_sess.span_diagnostic.emit_unused_externs(
214+
level,
215+
json_unused_externs.is_loud(),
216+
&unused_externs,
217+
);
212218
}
213219
}
214220
}
@@ -914,7 +920,7 @@ impl<'a> CrateLoader<'a> {
914920
}
915921

916922
// Got a real unused --extern
917-
if self.sess.opts.json_unused_externs {
923+
if self.sess.opts.json_unused_externs.is_enabled() {
918924
self.cstore.unused_externs.push(name_interned);
919925
continue;
920926
}

compiler/rustc_session/src/config.rs

+33-5
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ impl Default for Options {
757757
real_rust_source_base_dir: None,
758758
edition: DEFAULT_EDITION,
759759
json_artifact_notifications: false,
760-
json_unused_externs: false,
760+
json_unused_externs: JsonUnusedExterns::No,
761761
json_future_incompat: false,
762762
pretty: None,
763763
working_dir: RealFileName::LocalPath(std::env::current_dir().unwrap()),
@@ -1493,10 +1493,37 @@ pub fn parse_color(matches: &getopts::Matches) -> ColorConfig {
14931493
pub struct JsonConfig {
14941494
pub json_rendered: HumanReadableErrorType,
14951495
pub json_artifact_notifications: bool,
1496-
pub json_unused_externs: bool,
1496+
pub json_unused_externs: JsonUnusedExterns,
14971497
pub json_future_incompat: bool,
14981498
}
14991499

1500+
/// Report unused externs in event stream
1501+
#[derive(Copy, Clone)]
1502+
pub enum JsonUnusedExterns {
1503+
/// Do not
1504+
No,
1505+
/// Report, but do not exit with failure status for deny/forbid
1506+
Silent,
1507+
/// Report, and also exit with failure status for deny/forbid
1508+
Loud,
1509+
}
1510+
1511+
impl JsonUnusedExterns {
1512+
pub fn is_enabled(&self) -> bool {
1513+
match self {
1514+
JsonUnusedExterns::No => false,
1515+
JsonUnusedExterns::Loud | JsonUnusedExterns::Silent => true,
1516+
}
1517+
}
1518+
1519+
pub fn is_loud(&self) -> bool {
1520+
match self {
1521+
JsonUnusedExterns::No | JsonUnusedExterns::Silent => false,
1522+
JsonUnusedExterns::Loud => true,
1523+
}
1524+
}
1525+
}
1526+
15001527
/// Parse the `--json` flag.
15011528
///
15021529
/// The first value returned is how to render JSON diagnostics, and the second
@@ -1506,7 +1533,7 @@ pub fn parse_json(matches: &getopts::Matches) -> JsonConfig {
15061533
HumanReadableErrorType::Default;
15071534
let mut json_color = ColorConfig::Never;
15081535
let mut json_artifact_notifications = false;
1509-
let mut json_unused_externs = false;
1536+
let mut json_unused_externs = JsonUnusedExterns::No;
15101537
let mut json_future_incompat = false;
15111538
for option in matches.opt_strs("json") {
15121539
// For now conservatively forbid `--color` with `--json` since `--json`
@@ -1524,7 +1551,8 @@ pub fn parse_json(matches: &getopts::Matches) -> JsonConfig {
15241551
"diagnostic-short" => json_rendered = HumanReadableErrorType::Short,
15251552
"diagnostic-rendered-ansi" => json_color = ColorConfig::Always,
15261553
"artifacts" => json_artifact_notifications = true,
1527-
"unused-externs" => json_unused_externs = true,
1554+
"unused-externs" => json_unused_externs = JsonUnusedExterns::Loud,
1555+
"unused-externs-silent" => json_unused_externs = JsonUnusedExterns::Silent,
15281556
"future-incompat" => json_future_incompat = true,
15291557
s => early_error(
15301558
ErrorOutputType::default(),
@@ -2224,7 +2252,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
22242252

22252253
check_debug_option_stability(&debugging_opts, error_format, json_rendered);
22262254

2227-
if !debugging_opts.unstable_options && json_unused_externs {
2255+
if !debugging_opts.unstable_options && json_unused_externs.is_enabled() {
22282256
early_error(
22292257
error_format,
22302258
"the `-Z unstable-options` flag must also be passed to enable \

compiler/rustc_session/src/options.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ top_level_options!(
221221
json_artifact_notifications: bool [TRACKED],
222222

223223
/// `true` if we're emitting a JSON blob containing the unused externs
224-
json_unused_externs: bool [UNTRACKED],
224+
json_unused_externs: JsonUnusedExterns [UNTRACKED],
225225

226226
/// `true` if we're emitting a JSON job containing a future-incompat report for lints
227227
json_future_incompat: bool [TRACKED],

src/librustdoc/config.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ use rustc_session::config::{
1010
self, parse_crate_types_from_list, parse_externs, parse_target_triple, CrateType,
1111
};
1212
use rustc_session::config::{get_cmd_lint_options, nightly_options};
13-
use rustc_session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs};
13+
use rustc_session::config::{
14+
CodegenOptions, DebuggingOptions, ErrorOutputType, Externs, JsonUnusedExterns,
15+
};
1416
use rustc_session::getopts;
1517
use rustc_session::lint::Level;
1618
use rustc_session::search_paths::SearchPath;
@@ -147,7 +149,7 @@ crate struct Options {
147149
/// documentation.
148150
crate run_check: bool,
149151
/// Whether doctests should emit unused externs
150-
crate json_unused_externs: bool,
152+
crate json_unused_externs: JsonUnusedExterns,
151153
/// Whether to skip capturing stdout and stderr of tests.
152154
crate nocapture: bool,
153155

src/librustdoc/doctest.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ crate fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> {
168168

169169
// Collect and warn about unused externs, but only if we've gotten
170170
// reports for each doctest
171-
if json_unused_externs {
171+
if json_unused_externs.is_enabled() {
172172
let unused_extern_reports: Vec<_> =
173173
std::mem::take(&mut unused_extern_reports.lock().unwrap());
174174
if unused_extern_reports.len() == compiling_test_count {
@@ -337,7 +337,7 @@ fn run_test(
337337
if lang_string.test_harness {
338338
compiler.arg("--test");
339339
}
340-
if rustdoc_options.json_unused_externs && !lang_string.compile_fail {
340+
if rustdoc_options.json_unused_externs.is_enabled() && !lang_string.compile_fail {
341341
compiler.arg("--error-format=json");
342342
compiler.arg("--json").arg("unused-externs");
343343
compiler.arg("-Z").arg("unstable-options");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Check for unused crate dep, json event, deny but we're not reporting that in exit status
2+
3+
// edition:2018
4+
// check-pass
5+
// compile-flags: -Dunused-crate-dependencies -Zunstable-options --json unused-externs-silent --error-format=json
6+
// aux-crate:bar=bar.rs
7+
8+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"lint_level":"deny","unused_extern_names":["bar"]}

0 commit comments

Comments
 (0)