Skip to content

Commit

Permalink
Add --json unused-externs-silent with original behaviour
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jsgf committed Apr 27, 2022
1 parent 0529a13 commit c6bafa7
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 15 deletions.
9 changes: 7 additions & 2 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -969,10 +969,15 @@ impl Handler {
self.inner.borrow_mut().emitter.emit_future_breakage_report(diags)
}

pub fn emit_unused_externs(&self, lint_level: rustc_lint_defs::Level, unused_externs: &[&str]) {
pub fn emit_unused_externs(
&self,
lint_level: rustc_lint_defs::Level,
loud: bool,
unused_externs: &[&str],
) {
let mut inner = self.inner.borrow_mut();

if lint_level.is_error() {
if loud && lint_level.is_error() {
inner.bump_err_count();
}

Expand Down
12 changes: 9 additions & 3 deletions compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,12 @@ impl CStore {
}

pub fn report_unused_deps(&self, tcx: TyCtxt<'_>) {
let json_unused_externs = tcx.sess.opts.json_unused_externs;

// We put the check for the option before the lint_level_at_node call
// because the call mutates internal state and introducing it
// leads to some ui tests failing.
if !tcx.sess.opts.json_unused_externs {
if !json_unused_externs.is_enabled() {
return;
}
let level = tcx
Expand All @@ -208,7 +210,11 @@ impl CStore {
let unused_externs =
self.unused_externs.iter().map(|ident| ident.to_ident_string()).collect::<Vec<_>>();
let unused_externs = unused_externs.iter().map(String::as_str).collect::<Vec<&str>>();
tcx.sess.parse_sess.span_diagnostic.emit_unused_externs(level, &unused_externs);
tcx.sess.parse_sess.span_diagnostic.emit_unused_externs(
level,
json_unused_externs.is_loud(),
&unused_externs,
);
}
}
}
Expand Down Expand Up @@ -914,7 +920,7 @@ impl<'a> CrateLoader<'a> {
}

// Got a real unused --extern
if self.sess.opts.json_unused_externs {
if self.sess.opts.json_unused_externs.is_enabled() {
self.cstore.unused_externs.push(name_interned);
continue;
}
Expand Down
38 changes: 33 additions & 5 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ impl Default for Options {
real_rust_source_base_dir: None,
edition: DEFAULT_EDITION,
json_artifact_notifications: false,
json_unused_externs: false,
json_unused_externs: JsonUnusedExterns::No,
json_future_incompat: false,
pretty: None,
working_dir: RealFileName::LocalPath(std::env::current_dir().unwrap()),
Expand Down Expand Up @@ -1493,10 +1493,37 @@ pub fn parse_color(matches: &getopts::Matches) -> ColorConfig {
pub struct JsonConfig {
pub json_rendered: HumanReadableErrorType,
pub json_artifact_notifications: bool,
pub json_unused_externs: bool,
pub json_unused_externs: JsonUnusedExterns,
pub json_future_incompat: bool,
}

/// Report unused externs in event stream
#[derive(Copy, Clone)]
pub enum JsonUnusedExterns {
/// Do not
No,
/// Report, but do not exit with failure status for deny/forbid
Silent,
/// Report, and also exit with failure status for deny/forbid
Loud,
}

impl JsonUnusedExterns {
pub fn is_enabled(&self) -> bool {
match self {
JsonUnusedExterns::No => false,
JsonUnusedExterns::Loud | JsonUnusedExterns::Silent => true,
}
}

pub fn is_loud(&self) -> bool {
match self {
JsonUnusedExterns::No | JsonUnusedExterns::Silent => false,
JsonUnusedExterns::Loud => true,
}
}
}

/// Parse the `--json` flag.
///
/// The first value returned is how to render JSON diagnostics, and the second
Expand All @@ -1506,7 +1533,7 @@ pub fn parse_json(matches: &getopts::Matches) -> JsonConfig {
HumanReadableErrorType::Default;
let mut json_color = ColorConfig::Never;
let mut json_artifact_notifications = false;
let mut json_unused_externs = false;
let mut json_unused_externs = JsonUnusedExterns::No;
let mut json_future_incompat = false;
for option in matches.opt_strs("json") {
// For now conservatively forbid `--color` with `--json` since `--json`
Expand All @@ -1524,7 +1551,8 @@ pub fn parse_json(matches: &getopts::Matches) -> JsonConfig {
"diagnostic-short" => json_rendered = HumanReadableErrorType::Short,
"diagnostic-rendered-ansi" => json_color = ColorConfig::Always,
"artifacts" => json_artifact_notifications = true,
"unused-externs" => json_unused_externs = true,
"unused-externs" => json_unused_externs = JsonUnusedExterns::Loud,
"unused-externs-silent" => json_unused_externs = JsonUnusedExterns::Silent,
"future-incompat" => json_future_incompat = true,
s => early_error(
ErrorOutputType::default(),
Expand Down Expand Up @@ -2224,7 +2252,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {

check_debug_option_stability(&debugging_opts, error_format, json_rendered);

if !debugging_opts.unstable_options && json_unused_externs {
if !debugging_opts.unstable_options && json_unused_externs.is_enabled() {
early_error(
error_format,
"the `-Z unstable-options` flag must also be passed to enable \
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ top_level_options!(
json_artifact_notifications: bool [TRACKED],

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

/// `true` if we're emitting a JSON job containing a future-incompat report for lints
json_future_incompat: bool [TRACKED],
Expand Down
6 changes: 4 additions & 2 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ use rustc_session::config::{
self, parse_crate_types_from_list, parse_externs, parse_target_triple, CrateType,
};
use rustc_session::config::{get_cmd_lint_options, nightly_options};
use rustc_session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs};
use rustc_session::config::{
CodegenOptions, DebuggingOptions, ErrorOutputType, Externs, JsonUnusedExterns,
};
use rustc_session::getopts;
use rustc_session::lint::Level;
use rustc_session::search_paths::SearchPath;
Expand Down Expand Up @@ -147,7 +149,7 @@ crate struct Options {
/// documentation.
crate run_check: bool,
/// Whether doctests should emit unused externs
crate json_unused_externs: bool,
crate json_unused_externs: JsonUnusedExterns,
/// Whether to skip capturing stdout and stderr of tests.
crate nocapture: bool,

Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/doctest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ crate fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> {

// Collect and warn about unused externs, but only if we've gotten
// reports for each doctest
if json_unused_externs {
if json_unused_externs.is_enabled() {
let unused_extern_reports: Vec<_> =
std::mem::take(&mut unused_extern_reports.lock().unwrap());
if unused_extern_reports.len() == compiling_test_count {
Expand Down Expand Up @@ -337,7 +337,7 @@ fn run_test(
if lang_string.test_harness {
compiler.arg("--test");
}
if rustdoc_options.json_unused_externs && !lang_string.compile_fail {
if rustdoc_options.json_unused_externs.is_enabled() && !lang_string.compile_fail {
compiler.arg("--error-format=json");
compiler.arg("--json").arg("unused-externs");
compiler.arg("-Z").arg("unstable-options");
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/unused-crate-deps/deny-cmdline-json-silent.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Check for unused crate dep, json event, deny but we're not reporting that in exit status

// edition:2018
// check-pass
// compile-flags: -Dunused-crate-dependencies -Zunstable-options --json unused-externs-silent --error-format=json
// aux-crate:bar=bar.rs

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"lint_level":"deny","unused_extern_names":["bar"]}

0 comments on commit c6bafa7

Please sign in to comment.