Skip to content

Commit 8f096a2

Browse files
committed
Support overriding -A warnings level for a specific lint via command line
1 parent 5633798 commit 8f096a2

File tree

8 files changed

+113
-14
lines changed

8 files changed

+113
-14
lines changed

compiler/rustc_errors/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ pub static TRACK_DIAGNOSTICS: AtomicRef<fn(&mut Diagnostic, &mut dyn FnMut(&mut
490490
#[derive(Copy, Clone, Default)]
491491
pub struct HandlerFlags {
492492
/// If false, warning-level lints are suppressed.
493-
/// (rustc: see `--allow warnings` and `--cap-lints`)
493+
/// (rustc: see `--cap-lints`)
494494
pub can_emit_warnings: bool,
495495
/// If true, error-level diagnostics are upgraded to bug-level.
496496
/// (rustc: see `-Z treat-err-as-bug`)

compiler/rustc_interface/src/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ fn test_switch_implies_cfg_test_unless_cfg_test() {
157157
#[test]
158158
fn test_can_print_warnings() {
159159
rustc_span::create_default_session_globals_then(|| {
160-
let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap();
160+
let matches = optgroups().parse(&["--cap-lints=allow".to_string()]).unwrap();
161161
let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
162162
let (sess, _) = mk_session(&mut handler, matches);
163163
assert!(!sess.diagnostic().can_emit_warnings());

compiler/rustc_middle/src/lint.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ pub fn reveal_actual_level(
7575
src: &mut LintLevelSource,
7676
sess: &Session,
7777
lint: LintId,
78-
probe_for_lint_level: impl FnOnce(LintId) -> (Option<Level>, LintLevelSource),
78+
probe_for_lint_level: impl Fn(LintId) -> (Option<Level>, LintLevelSource),
7979
) -> Level {
8080
// If `level` is none then we actually assume the default level for this lint.
8181
let mut level = level.unwrap_or_else(|| lint.lint.default_level(sess.edition()));
@@ -90,8 +90,20 @@ pub fn reveal_actual_level(
9090
// future compatibility warning.
9191
if level == Level::Warn && lint != LintId::of(FORBIDDEN_LINT_GROUPS) {
9292
let (warnings_level, warnings_src) = probe_for_lint_level(LintId::of(builtin::WARNINGS));
93-
if let Some(configured_warning_level) = warnings_level {
94-
if configured_warning_level != Level::Warn {
93+
if let Some(configured_warning_level) = warnings_level
94+
&& configured_warning_level != Level::Warn
95+
{
96+
if matches!(warnings_src, LintLevelSource::CommandLine(..))
97+
&& lint != LintId::of(builtin::WARNINGS)
98+
&& let (Some(lint_level), lint_src) = probe_for_lint_level(lint)
99+
&& matches!(lint_src, LintLevelSource::CommandLine(..))
100+
{
101+
// We have a command-line `-Awarnings` *and* a command-line e.g. `-Wspecific-lint`.
102+
// Let's have the `specific-lint`'s command-line level override the command-line
103+
// `warnings` level.
104+
level = lint_level;
105+
*src = lint_src;
106+
} else {
95107
level = configured_warning_level;
96108
*src = warnings_src;
97109
}

compiler/rustc_session/src/session.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,16 +1393,8 @@ pub fn build_session(
13931393
target_override: Option<Target>,
13941394
cfg_version: &'static str,
13951395
) -> Session {
1396-
// FIXME: This is not general enough to make the warning lint completely override
1397-
// normal diagnostic warnings, since the warning lint can also be denied and changed
1398-
// later via the source code.
1399-
let warnings_allow = sopts
1400-
.lint_opts
1401-
.iter()
1402-
.rfind(|&(key, _)| *key == "warnings")
1403-
.is_some_and(|&(_, level)| level == lint::Allow);
14041396
let cap_lints_allow = sopts.lint_cap.is_some_and(|cap| cap == lint::Allow);
1405-
let can_emit_warnings = !(warnings_allow || cap_lints_allow);
1397+
let can_emit_warnings = !cap_lints_allow;
14061398

14071399
let sysroot = match &sopts.maybe_sysroot {
14081400
Some(sysroot) => sysroot.clone(),
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// compile-flags: -A warnings
2+
3+
fn main() {
4+
// This will be overriden by the `-A warnings` command line option.
5+
#[warn(non_snake_case)]
6+
let _OwO = 0u8;
7+
8+
// But this should not.
9+
#[deny(non_snake_case)]
10+
let _UwU = 0u8;
11+
//~^ ERROR variable `_UwU` should have a snake case name
12+
13+
bar();
14+
baz();
15+
}
16+
17+
#[warn(warnings)]
18+
fn bar() {
19+
let _OwO = 0u8;
20+
//~^ WARN variable `_OwO` should have a snake case name
21+
}
22+
23+
#[deny(warnings)]
24+
fn baz() {
25+
let _OwO = 0u8;
26+
//~^ ERROR variable `_OwO` should have a snake case name
27+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
error: variable `_UwU` should have a snake case name
2+
--> $DIR/command-line-allow-warnings.rs:10:9
3+
|
4+
LL | let _UwU = 0u8;
5+
| ^^^^ help: convert the identifier to snake case: `_uw_u`
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/command-line-allow-warnings.rs:9:12
9+
|
10+
LL | #[deny(non_snake_case)]
11+
| ^^^^^^^^^^^^^^
12+
13+
warning: variable `_OwO` should have a snake case name
14+
--> $DIR/command-line-allow-warnings.rs:19:9
15+
|
16+
LL | let _OwO = 0u8;
17+
| ^^^^ help: convert the identifier to snake case: `_ow_o`
18+
|
19+
= note: `#[warn(non_snake_case)]` on by default
20+
21+
error: variable `_OwO` should have a snake case name
22+
--> $DIR/command-line-allow-warnings.rs:25:9
23+
|
24+
LL | let _OwO = 0u8;
25+
| ^^^^ help: convert the identifier to snake case: `_ow_o`
26+
|
27+
note: the lint level is defined here
28+
--> $DIR/command-line-allow-warnings.rs:23:8
29+
|
30+
LL | #[deny(warnings)]
31+
| ^^^^^^^^
32+
= note: `#[deny(non_snake_case)]` implied by `#[deny(warnings)]`
33+
34+
error: aborting due to 2 previous errors; 1 warning emitted
35+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// compile-flags: -A warnings -W unused-variables
2+
3+
fn main() {
4+
let x = 0u8;
5+
//~^ WARNING unused variable
6+
7+
// Source code lint level should override command-line lint level in any case.
8+
#[deny(unused_variables)]
9+
let y = 0u8;
10+
//~^ ERROR unused variable
11+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
warning: unused variable: `x`
2+
--> $DIR/command-line-lint-level-specific-lint.rs:4:9
3+
|
4+
LL | let x = 0u8;
5+
| ^ help: if this is intentional, prefix it with an underscore: `_x`
6+
|
7+
= note: requested on the command line with `-W unused-variables`
8+
9+
error: unused variable: `y`
10+
--> $DIR/command-line-lint-level-specific-lint.rs:9:9
11+
|
12+
LL | let y = 0u8;
13+
| ^ help: if this is intentional, prefix it with an underscore: `_y`
14+
|
15+
note: the lint level is defined here
16+
--> $DIR/command-line-lint-level-specific-lint.rs:8:12
17+
|
18+
LL | #[deny(unused_variables)]
19+
| ^^^^^^^^^^^^^^^^
20+
21+
error: aborting due to previous error; 1 warning emitted
22+

0 commit comments

Comments
 (0)