Skip to content

Commit 2b621e3

Browse files
Rollup merge of rust-lang#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 rust-lang#86958, which arose from the special-cased handling of `ForceWarn` having had an error in it.
2 parents 2636682 + dbdce6e commit 2b621e3

10 files changed

+91
-47
lines changed

compiler/rustc_lint/src/levels.rs

+5-19
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ use rustc_span::symbol::{sym, Symbol};
2626
use rustc_span::{source_map::MultiSpan, Span, DUMMY_SP};
2727
use tracing::debug;
2828

29-
use std::cmp;
30-
3129
fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap {
3230
let store = unerased_lint_store(tcx);
3331
let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID);
@@ -91,36 +89,24 @@ impl<'s> LintLevelsBuilder<'s> {
9189
for &(ref lint_name, level) in &sess.opts.lint_opts {
9290
store.check_lint_name_cmdline(sess, &lint_name, level, self.crate_attrs);
9391
let orig_level = level;
94-
95-
// If the cap is less than this specified level, e.g., if we've got
96-
// `--cap-lints allow` but we've also got `-D foo` then we ignore
97-
// this specification as the lint cap will set it to allow anyway.
98-
let level = cmp::min(level, self.sets.lint_cap);
99-
10092
let lint_flag_val = Symbol::intern(lint_name);
10193

10294
let ids = match store.find_lints(&lint_name) {
10395
Ok(ids) => ids,
10496
Err(_) => continue, // errors handled in check_lint_name_cmdline above
10597
};
10698
for id in ids {
99+
// ForceWarn and Forbid cannot be overriden
100+
if let Some((Level::ForceWarn | Level::Forbid, _)) = specs.get(&id) {
101+
continue;
102+
}
103+
107104
self.check_gated_lint(id, DUMMY_SP);
108105
let src = LintLevelSource::CommandLine(lint_flag_val, orig_level);
109106
specs.insert(id, (level, src));
110107
}
111108
}
112109

113-
for lint_name in &sess.opts.force_warns {
114-
store.check_lint_name_cmdline(sess, lint_name, Level::ForceWarn, self.crate_attrs);
115-
let lints = store
116-
.find_lints(lint_name)
117-
.unwrap_or_else(|_| bug!("A valid lint failed to produce a lint ids"));
118-
for id in lints {
119-
let src = LintLevelSource::CommandLine(Symbol::intern(lint_name), Level::ForceWarn);
120-
specs.insert(id, (Level::ForceWarn, src));
121-
}
122-
}
123-
124110
self.cur = self.sets.list.push(LintSet { specs, parent: COMMAND_LINE });
125111
}
126112

compiler/rustc_session/src/config.rs

+13-26
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,6 @@ impl Default for Options {
677677
optimize: OptLevel::No,
678678
debuginfo: DebugInfo::None,
679679
lint_opts: Vec::new(),
680-
force_warns: Vec::new(),
681680
lint_cap: None,
682681
describe_lints: false,
683682
output_types: OutputTypes(BTreeMap::new()),
@@ -1172,20 +1171,20 @@ pub fn get_cmd_lint_options(
11721171
matches: &getopts::Matches,
11731172
error_format: ErrorOutputType,
11741173
debugging_opts: &DebuggingOptions,
1175-
) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>, Vec<String>) {
1174+
) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>) {
11761175
let mut lint_opts_with_position = vec![];
11771176
let mut describe_lints = false;
11781177

1179-
for level in [lint::Allow, lint::Warn, lint::Deny, lint::Forbid] {
1180-
for (passed_arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
1181-
let arg_pos = if let lint::Forbid = level {
1182-
// HACK: forbid is always specified last, so it can't be overridden.
1183-
// FIXME: remove this once <https://github.com/rust-lang/rust/issues/70819> is
1184-
// fixed and `forbid` works as expected.
1185-
usize::MAX
1186-
} else {
1187-
passed_arg_pos
1188-
};
1178+
if !debugging_opts.unstable_options && matches.opt_present("force-warns") {
1179+
early_error(
1180+
error_format,
1181+
"the `-Z unstable-options` flag must also be passed to enable \
1182+
the flag `--force-warns=lints`",
1183+
);
1184+
}
1185+
1186+
for level in [lint::Allow, lint::Warn, lint::ForceWarn, lint::Deny, lint::Forbid] {
1187+
for (arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
11891188
if lint_name == "help" {
11901189
describe_lints = true;
11911190
} else {
@@ -1206,18 +1205,7 @@ pub fn get_cmd_lint_options(
12061205
.unwrap_or_else(|| early_error(error_format, &format!("unknown lint level: `{}`", cap)))
12071206
});
12081207

1209-
if !debugging_opts.unstable_options && matches.opt_present("force-warns") {
1210-
early_error(
1211-
error_format,
1212-
"the `-Z unstable-options` flag must also be passed to enable \
1213-
the flag `--force-warns=lints`",
1214-
);
1215-
}
1216-
1217-
let force_warns =
1218-
matches.opt_strs("force-warns").into_iter().map(|name| name.replace('-', "_")).collect();
1219-
1220-
(lint_opts, describe_lints, lint_cap, force_warns)
1208+
(lint_opts, describe_lints, lint_cap)
12211209
}
12221210

12231211
/// Parses the `--color` flag.
@@ -1955,7 +1943,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
19551943
.unwrap_or_else(|e| early_error(error_format, &e[..]));
19561944

19571945
let mut debugging_opts = DebuggingOptions::build(matches, error_format);
1958-
let (lint_opts, describe_lints, lint_cap, force_warns) =
1946+
let (lint_opts, describe_lints, lint_cap) =
19591947
get_cmd_lint_options(matches, error_format, &debugging_opts);
19601948

19611949
check_debug_option_stability(&debugging_opts, error_format, json_rendered);
@@ -2129,7 +2117,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
21292117
optimize: opt_level,
21302118
debuginfo,
21312119
lint_opts,
2132-
force_warns,
21332120
lint_cap,
21342121
describe_lints,
21352122
output_types,

compiler/rustc_session/src/options.rs

-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ top_level_options!(
135135
debuginfo: DebugInfo [TRACKED],
136136
lint_opts: Vec<(String, lint::Level)> [TRACKED],
137137
lint_cap: Option<lint::Level> [TRACKED],
138-
force_warns: Vec<String> [TRACKED],
139138
describe_lints: bool [UNTRACKED],
140139
output_types: OutputTypes [TRACKED],
141140
search_paths: Vec<SearchPath> [UNTRACKED],

src/librustdoc/config.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,7 @@ impl Options {
628628
let generate_redirect_map = matches.opt_present("generate-redirect-map");
629629
let show_type_layout = matches.opt_present("show-type-layout");
630630

631-
let (lint_opts, describe_lints, lint_cap, _) =
631+
let (lint_opts, describe_lints, lint_cap) =
632632
get_cmd_lint_options(matches, error_format, &debugging_opts);
633633

634634
Ok(Options {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: extern declarations without an explicit ABI are deprecated
2+
--> $DIR/cli-lint-override.rs:12:1
3+
|
4+
LL | extern fn foo() {}
5+
| ^^^^^^^^^^^^^^^ ABI should be specified here
6+
|
7+
= note: requested on the command line with `-F missing-abi`
8+
= help: the default ABI is C
9+
10+
error: aborting due to previous error
11+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
warning: extern declarations without an explicit ABI are deprecated
2+
--> $DIR/cli-lint-override.rs:12:1
3+
|
4+
LL | extern fn foo() {}
5+
| ^^^^^^^^^^^^^^^ ABI should be specified here
6+
|
7+
= note: requested on the command line with `--force-warns missing-abi`
8+
= help: the default ABI is C
9+
10+
warning: 1 warning emitted
11+

src/test/ui/lint/cli-lint-override.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Tests that subsequent lints specified via the command line override
2+
// each other, except for ForceWarn and Forbid, which cannot be overriden.
3+
//
4+
// revisions: warn_deny forbid_warn force_warn_deny
5+
//
6+
//[warn_deny] compile-flags: --warn missing_abi --deny missing_abi
7+
//[forbid_warn] compile-flags: --warn missing_abi --forbid missing_abi
8+
//[force_warn_deny] compile-flags: -Z unstable-options --force-warns missing_abi --allow missing_abi
9+
//[force_warn_deny] check-pass
10+
11+
12+
extern fn foo() {}
13+
//[warn_deny]~^ ERROR extern declarations without an explicit ABI are deprecated
14+
//[forbid_warn]~^^ ERROR extern declarations without an explicit ABI are deprecated
15+
//[force_warn_deny]~^^^ WARN extern declarations without an explicit ABI are deprecated
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: extern declarations without an explicit ABI are deprecated
2+
--> $DIR/cli-lint-override.rs:12:1
3+
|
4+
LL | extern fn foo() {}
5+
| ^^^^^^^^^^^^^^^ ABI should be specified here
6+
|
7+
= note: requested on the command line with `-D missing-abi`
8+
= help: the default ABI is C
9+
10+
error: aborting due to previous error
11+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Checks that rustc correctly errors when passed an invalid lint with
2+
// `--force-warns`. This is a regression test for issue #86958.
3+
//
4+
// compile-flags: -Z unstable-options --force-warns foo-qux
5+
// error-pattern: unknown lint: `foo_qux`
6+
7+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0602]: unknown lint: `foo_qux`
2+
|
3+
= note: requested on the command line with `--force-warns foo_qux`
4+
5+
error[E0602]: unknown lint: `foo_qux`
6+
|
7+
= note: requested on the command line with `--force-warns foo_qux`
8+
9+
error[E0602]: unknown lint: `foo_qux`
10+
|
11+
= note: requested on the command line with `--force-warns foo_qux`
12+
13+
error: aborting due to 3 previous errors
14+
15+
For more information about this error, try `rustc --explain E0602`.

0 commit comments

Comments
 (0)