Skip to content

Commit 69a19bf

Browse files
committed
Initial support for force-warns
1 parent ce0d64e commit 69a19bf

13 files changed

+146
-7
lines changed

compiler/rustc_lint/src/levels.rs

+9
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ impl<'s> LintLevelsBuilder<'s> {
109109
}
110110
}
111111

112+
for lint_name in &sess.opts.force_warns {
113+
store.check_lint_name_cmdline(sess, &lint_name, Level::Allow); // FIXME level is wrong
114+
self.sets.force_warns.insert(lint_name.to_uppercase());
115+
}
116+
112117
self.sets.list.push(LintSet::CommandLine { specs });
113118
}
114119

@@ -142,6 +147,9 @@ impl<'s> LintLevelsBuilder<'s> {
142147
LintLevelSource::Default => false,
143148
LintLevelSource::Node(symbol, _, _) => self.store.is_lint_group(symbol),
144149
LintLevelSource::CommandLine(symbol, _) => self.store.is_lint_group(symbol),
150+
LintLevelSource::ForceWarn(symbol) => {
151+
bug!("forced warn lint returned a forbid lint level")
152+
}
145153
};
146154
debug!(
147155
"fcw_warning={:?}, specs.get(&id) = {:?}, old_src={:?}, id_name={:?}",
@@ -166,6 +174,7 @@ impl<'s> LintLevelsBuilder<'s> {
166174
LintLevelSource::CommandLine(_, _) => {
167175
diag_builder.note("`forbid` lint level was set on command line");
168176
}
177+
_ => bug!("forced warn lint returned a forbid lint level"),
169178
}
170179
diag_builder.emit();
171180
};

compiler/rustc_middle/src/lint.rs

+27-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::cmp;
22

33
use crate::ich::StableHashingContext;
4-
use rustc_data_structures::fx::FxHashMap;
4+
use chalk_ir::Substitution;
5+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
56
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
67
use rustc_errors::{DiagnosticBuilder, DiagnosticId};
78
use rustc_hir::HirId;
@@ -28,6 +29,9 @@ pub enum LintLevelSource {
2829
/// The provided `Level` is the level specified on the command line.
2930
/// (The actual level may be lower due to `--cap-lints`.)
3031
CommandLine(Symbol, Level),
32+
33+
/// Lint is being forced to warn no matter what.
34+
ForceWarn(Symbol),
3135
}
3236

3337
impl LintLevelSource {
@@ -36,6 +40,7 @@ impl LintLevelSource {
3640
LintLevelSource::Default => symbol::kw::Default,
3741
LintLevelSource::Node(name, _, _) => name,
3842
LintLevelSource::CommandLine(name, _) => name,
43+
LintLevelSource::ForceWarn(name) => name,
3944
}
4045
}
4146

@@ -44,6 +49,7 @@ impl LintLevelSource {
4449
LintLevelSource::Default => DUMMY_SP,
4550
LintLevelSource::Node(_, span, _) => span,
4651
LintLevelSource::CommandLine(_, _) => DUMMY_SP,
52+
LintLevelSource::ForceWarn(_) => DUMMY_SP,
4753
}
4854
}
4955
}
@@ -55,6 +61,7 @@ pub type LevelAndSource = (Level, LintLevelSource);
5561
pub struct LintLevelSets {
5662
pub list: Vec<LintSet>,
5763
pub lint_cap: Level,
64+
pub force_warns: FxHashSet<String>,
5865
}
5966

6067
#[derive(Debug)]
@@ -73,7 +80,11 @@ pub enum LintSet {
7380

7481
impl LintLevelSets {
7582
pub fn new() -> Self {
76-
LintLevelSets { list: Vec::new(), lint_cap: Level::Forbid }
83+
LintLevelSets {
84+
list: Vec::new(),
85+
lint_cap: Level::Forbid,
86+
force_warns: FxHashSet::default(),
87+
}
7788
}
7889

7990
pub fn get_lint_level(
@@ -83,6 +94,11 @@ impl LintLevelSets {
8394
aux: Option<&FxHashMap<LintId, LevelAndSource>>,
8495
sess: &Session,
8596
) -> LevelAndSource {
97+
// Check whether we should always warn
98+
if self.force_warns.contains(lint.name) {
99+
return (Level::Warn, LintLevelSource::ForceWarn(Symbol::intern(lint.name)));
100+
}
101+
86102
let (level, mut src) = self.get_lint_id_level(LintId::of(lint), idx, aux);
87103

88104
// If `level` is none then we actually assume the default level for this
@@ -176,11 +192,11 @@ impl LintLevelMap {
176192
impl<'a> HashStable<StableHashingContext<'a>> for LintLevelMap {
177193
#[inline]
178194
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
179-
let LintLevelMap { ref sets, ref id_to_set } = *self;
195+
let LintLevelMap { ref sets, ref id_to_set, .. } = *self;
180196

181197
id_to_set.hash_stable(hcx, hasher);
182198

183-
let LintLevelSets { ref list, lint_cap } = *sets;
199+
let LintLevelSets { ref list, lint_cap, .. } = *sets;
184200

185201
lint_cap.hash_stable(hcx, hasher);
186202

@@ -346,6 +362,13 @@ pub fn struct_lint_level<'s, 'd>(
346362
);
347363
}
348364
}
365+
LintLevelSource::ForceWarn(_) => {
366+
sess.diag_note_once(
367+
&mut err,
368+
DiagnosticMessageId::from(lint),
369+
"Warning forced by `force-warns` commandline option",
370+
);
371+
}
349372
}
350373

351374
err.code(DiagnosticId::Lint { name, has_future_breakage });

compiler/rustc_session/src/config.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@ impl Default for Options {
677677
optimize: OptLevel::No,
678678
debuginfo: DebugInfo::None,
679679
lint_opts: Vec::new(),
680+
force_warns: Vec::new(),
680681
lint_cap: None,
681682
describe_lints: false,
682683
output_types: OutputTypes(BTreeMap::new()),
@@ -1092,6 +1093,13 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
10921093
level",
10931094
"LEVEL",
10941095
),
1096+
opt::multi_s(
1097+
"",
1098+
"force-warns",
1099+
"Specifiy lints that should warn even if \
1100+
they are allowed somewhere else",
1101+
"LINT",
1102+
),
10951103
opt::multi_s("C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
10961104
opt::flag_s("V", "version", "Print version info and exit"),
10971105
opt::flag_s("v", "verbose", "Use verbose output"),
@@ -1156,7 +1164,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
11561164
pub fn get_cmd_lint_options(
11571165
matches: &getopts::Matches,
11581166
error_format: ErrorOutputType,
1159-
) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>) {
1167+
) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>, Vec<String>) {
11601168
let mut lint_opts_with_position = vec![];
11611169
let mut describe_lints = false;
11621170

@@ -1189,7 +1197,10 @@ pub fn get_cmd_lint_options(
11891197
lint::Level::from_str(&cap)
11901198
.unwrap_or_else(|| early_error(error_format, &format!("unknown lint level: `{}`", cap)))
11911199
});
1192-
(lint_opts, describe_lints, lint_cap)
1200+
1201+
let force_warns = matches.opt_strs("force-warns");
1202+
1203+
(lint_opts, describe_lints, lint_cap, force_warns)
11931204
}
11941205

11951206
/// Parses the `--color` flag.
@@ -1926,7 +1937,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
19261937
let crate_types = parse_crate_types_from_list(unparsed_crate_types)
19271938
.unwrap_or_else(|e| early_error(error_format, &e[..]));
19281939

1929-
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
1940+
let (lint_opts, describe_lints, lint_cap, force_warns) =
1941+
get_cmd_lint_options(matches, error_format);
19301942

19311943
let mut debugging_opts = DebuggingOptions::build(matches, error_format);
19321944
check_debug_option_stability(&debugging_opts, error_format, json_rendered);
@@ -2100,6 +2112,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
21002112
optimize: opt_level,
21012113
debuginfo,
21022114
lint_opts,
2115+
force_warns,
21032116
lint_cap,
21042117
describe_lints,
21052118
output_types,

compiler/rustc_session/src/options.rs

+1
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ top_level_options!(
130130
debuginfo: DebugInfo [TRACKED],
131131
lint_opts: Vec<(String, lint::Level)> [TRACKED],
132132
lint_cap: Option<lint::Level> [TRACKED],
133+
force_warns: Vec<String> [TRACKED],
133134
describe_lints: bool [UNTRACKED],
134135
output_types: OutputTypes [TRACKED],
135136
search_paths: Vec<SearchPath> [UNTRACKED],
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// compile-flags: --force-warns dead_code
2+
// check-pass
3+
4+
#![allow(warnings)]
5+
6+
fn dead_function() {}
7+
//~^ WARN function is never used
8+
9+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
warning: function is never used: `dead_function`
2+
--> $DIR/force-allow-all-warnings.rs:6:4
3+
|
4+
LL | fn dead_function() {}
5+
| ^^^^^^^^^^^^^
6+
|
7+
= note: Warning forced by `force-warns` commandline option
8+
9+
warning: 1 warning emitted
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// compile-flags: --force-warns elided_lifetimes_in_paths
2+
// check-pass
3+
4+
struct Foo<'a> {
5+
x: &'a u32,
6+
}
7+
8+
fn foo(x: &Foo) {}
9+
//~^ WARN hidden lifetime parameters in types are deprecated
10+
11+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
warning: hidden lifetime parameters in types are deprecated
2+
--> $DIR/force-allow-by-default.rs:8:12
3+
|
4+
LL | fn foo(x: &Foo) {}
5+
| ^^^- help: indicate the anonymous lifetime: `<'_>`
6+
|
7+
= note: Warning forced by `force-warns` commandline option
8+
9+
warning: 1 warning emitted
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// ignore-test
2+
// compile-flags: --force-warns arithmetic_overflow
3+
// check-pass
4+
5+
#![allow(arithmetic_overflow)]
6+
7+
fn main() {
8+
1_i32 << 32;
9+
//~^ WARN this arithmetic operation will overflow
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// compile-flags: --force-warns bare_trait_objects
2+
// check-pass
3+
4+
#![allow(rust_2018_compatibility)]
5+
6+
pub trait SomeTrait {}
7+
8+
pub fn function(_x: Box<SomeTrait>) {}
9+
//~^ WARN trait objects without an explicit `dyn` are deprecated
10+
//~| WARN this was previously accepted by the compiler
11+
12+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
warning: trait objects without an explicit `dyn` are deprecated
2+
--> $DIR/force-allowed-group.rs:8:25
3+
|
4+
LL | pub fn function(_x: Box<SomeTrait>) {}
5+
| ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
6+
|
7+
= note: Warning forced by `force-warns` commandline option
8+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
9+
= note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
10+
11+
warning: 1 warning emitted
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// compile-flags: --force-warns dead_code
2+
// check-pass
3+
4+
#![allow(dead_code)]
5+
6+
fn dead_function() {}
7+
//~^ WARN function is never used
8+
9+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
warning: function is never used: `dead_function`
2+
--> $DIR/force-allowed-warning.rs:6:4
3+
|
4+
LL | fn dead_function() {}
5+
| ^^^^^^^^^^^^^
6+
|
7+
= note: Warning forced by `force-warns` commandline option
8+
9+
warning: 1 warning emitted
10+

0 commit comments

Comments
 (0)