Auto merge of #86970 - inquisitivecrystal:force-warn, r=davidtwco

Make `--force-warns` a normal lint level option

Now that `ForceWarn` is a lint level, there's no reason `--force-warns` should be treated differently from other options that set lint levels. This merges the `ForceWarn` handling in with the other lint level command line options. It also unifies all of the relevant selection logic in `compiler/rustc_lint/src/levels.rs`, rather than having some of it weirdly elsewhere.

Fixes #86958, which arose from the special-cased handling of `ForceWarn` having had an error in it.
This commit is contained in:
bors 2021-07-19 13:18:04 +00:00
commit b543e0dc03
10 changed files with 91 additions and 47 deletions

View File

@ -26,8 +26,6 @@ use rustc_span::symbol::{sym, Symbol};
use rustc_span::{source_map::MultiSpan, Span, DUMMY_SP};
use tracing::debug;
use std::cmp;
fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap {
let store = unerased_lint_store(tcx);
let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID);
@ -91,12 +89,6 @@ impl<'s> LintLevelsBuilder<'s> {
for &(ref lint_name, level) in &sess.opts.lint_opts {
store.check_lint_name_cmdline(sess, &lint_name, level, self.crate_attrs);
let orig_level = level;
// If the cap is less than this specified level, e.g., if we've got
// `--cap-lints allow` but we've also got `-D foo` then we ignore
// this specification as the lint cap will set it to allow anyway.
let level = cmp::min(level, self.sets.lint_cap);
let lint_flag_val = Symbol::intern(lint_name);
let ids = match store.find_lints(&lint_name) {
@ -104,23 +96,17 @@ impl<'s> LintLevelsBuilder<'s> {
Err(_) => continue, // errors handled in check_lint_name_cmdline above
};
for id in ids {
// ForceWarn and Forbid cannot be overriden
if let Some((Level::ForceWarn | Level::Forbid, _)) = specs.get(&id) {
continue;
}
self.check_gated_lint(id, DUMMY_SP);
let src = LintLevelSource::CommandLine(lint_flag_val, orig_level);
specs.insert(id, (level, src));
}
}
for lint_name in &sess.opts.force_warns {
store.check_lint_name_cmdline(sess, lint_name, Level::ForceWarn, self.crate_attrs);
let lints = store
.find_lints(lint_name)
.unwrap_or_else(|_| bug!("A valid lint failed to produce a lint ids"));
for id in lints {
let src = LintLevelSource::CommandLine(Symbol::intern(lint_name), Level::ForceWarn);
specs.insert(id, (Level::ForceWarn, src));
}
}
self.cur = self.sets.list.push(LintSet { specs, parent: COMMAND_LINE });
}

View File

@ -677,7 +677,6 @@ impl Default for Options {
optimize: OptLevel::No,
debuginfo: DebugInfo::None,
lint_opts: Vec::new(),
force_warns: Vec::new(),
lint_cap: None,
describe_lints: false,
output_types: OutputTypes(BTreeMap::new()),
@ -1172,20 +1171,20 @@ pub fn get_cmd_lint_options(
matches: &getopts::Matches,
error_format: ErrorOutputType,
debugging_opts: &DebuggingOptions,
) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>, Vec<String>) {
) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>) {
let mut lint_opts_with_position = vec![];
let mut describe_lints = false;
for level in [lint::Allow, lint::Warn, lint::Deny, lint::Forbid] {
for (passed_arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
let arg_pos = if let lint::Forbid = level {
// HACK: forbid is always specified last, so it can't be overridden.
// FIXME: remove this once <https://github.com/rust-lang/rust/issues/70819> is
// fixed and `forbid` works as expected.
usize::MAX
} else {
passed_arg_pos
};
if !debugging_opts.unstable_options && matches.opt_present("force-warns") {
early_error(
error_format,
"the `-Z unstable-options` flag must also be passed to enable \
the flag `--force-warns=lints`",
);
}
for level in [lint::Allow, lint::Warn, lint::ForceWarn, lint::Deny, lint::Forbid] {
for (arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
if lint_name == "help" {
describe_lints = true;
} else {
@ -1206,18 +1205,7 @@ pub fn get_cmd_lint_options(
.unwrap_or_else(|| early_error(error_format, &format!("unknown lint level: `{}`", cap)))
});
if !debugging_opts.unstable_options && matches.opt_present("force-warns") {
early_error(
error_format,
"the `-Z unstable-options` flag must also be passed to enable \
the flag `--force-warns=lints`",
);
}
let force_warns =
matches.opt_strs("force-warns").into_iter().map(|name| name.replace('-', "_")).collect();
(lint_opts, describe_lints, lint_cap, force_warns)
(lint_opts, describe_lints, lint_cap)
}
/// Parses the `--color` flag.
@ -1955,7 +1943,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
.unwrap_or_else(|e| early_error(error_format, &e[..]));
let mut debugging_opts = DebuggingOptions::build(matches, error_format);
let (lint_opts, describe_lints, lint_cap, force_warns) =
let (lint_opts, describe_lints, lint_cap) =
get_cmd_lint_options(matches, error_format, &debugging_opts);
check_debug_option_stability(&debugging_opts, error_format, json_rendered);
@ -2129,7 +2117,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
optimize: opt_level,
debuginfo,
lint_opts,
force_warns,
lint_cap,
describe_lints,
output_types,

View File

@ -135,7 +135,6 @@ top_level_options!(
debuginfo: DebugInfo [TRACKED],
lint_opts: Vec<(String, lint::Level)> [TRACKED_NO_CRATE_HASH],
lint_cap: Option<lint::Level> [TRACKED_NO_CRATE_HASH],
force_warns: Vec<String> [TRACKED_NO_CRATE_HASH],
describe_lints: bool [UNTRACKED],
output_types: OutputTypes [TRACKED],
search_paths: Vec<SearchPath> [UNTRACKED],

View File

@ -632,7 +632,7 @@ impl Options {
let show_type_layout = matches.opt_present("show-type-layout");
let nocapture = matches.opt_present("nocapture");
let (lint_opts, describe_lints, lint_cap, _) =
let (lint_opts, describe_lints, lint_cap) =
get_cmd_lint_options(matches, error_format, &debugging_opts);
Ok(Options {

View File

@ -0,0 +1,11 @@
error: extern declarations without an explicit ABI are deprecated
--> $DIR/cli-lint-override.rs:12:1
|
LL | extern fn foo() {}
| ^^^^^^^^^^^^^^^ ABI should be specified here
|
= note: requested on the command line with `-F missing-abi`
= help: the default ABI is C
error: aborting due to previous error

View File

@ -0,0 +1,11 @@
warning: extern declarations without an explicit ABI are deprecated
--> $DIR/cli-lint-override.rs:12:1
|
LL | extern fn foo() {}
| ^^^^^^^^^^^^^^^ ABI should be specified here
|
= note: requested on the command line with `--force-warns missing-abi`
= help: the default ABI is C
warning: 1 warning emitted

View File

@ -0,0 +1,17 @@
// Tests that subsequent lints specified via the command line override
// each other, except for ForceWarn and Forbid, which cannot be overriden.
//
// revisions: warn_deny forbid_warn force_warn_deny
//
//[warn_deny] compile-flags: --warn missing_abi --deny missing_abi
//[forbid_warn] compile-flags: --warn missing_abi --forbid missing_abi
//[force_warn_deny] compile-flags: -Z unstable-options --force-warns missing_abi --allow missing_abi
//[force_warn_deny] check-pass
extern fn foo() {}
//[warn_deny]~^ ERROR extern declarations without an explicit ABI are deprecated
//[forbid_warn]~^^ ERROR extern declarations without an explicit ABI are deprecated
//[force_warn_deny]~^^^ WARN extern declarations without an explicit ABI are deprecated
fn main() {}

View File

@ -0,0 +1,11 @@
error: extern declarations without an explicit ABI are deprecated
--> $DIR/cli-lint-override.rs:12:1
|
LL | extern fn foo() {}
| ^^^^^^^^^^^^^^^ ABI should be specified here
|
= note: requested on the command line with `-D missing-abi`
= help: the default ABI is C
error: aborting due to previous error

View File

@ -0,0 +1,7 @@
// Checks that rustc correctly errors when passed an invalid lint with
// `--force-warns`. This is a regression test for issue #86958.
//
// compile-flags: -Z unstable-options --force-warns foo-qux
// error-pattern: unknown lint: `foo_qux`
fn main() {}

View File

@ -0,0 +1,15 @@
error[E0602]: unknown lint: `foo_qux`
|
= note: requested on the command line with `--force-warns foo_qux`
error[E0602]: unknown lint: `foo_qux`
|
= note: requested on the command line with `--force-warns foo_qux`
error[E0602]: unknown lint: `foo_qux`
|
= note: requested on the command line with `--force-warns foo_qux`
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0602`.