Make ForceWarn a lint level.
Follow-up to #85788
cc `@rylev`
}
}
- /// Checks the validity of lint names derived from the command line. Returns
- /// true if the lint is valid, false otherwise.
- pub fn check_lint_name_cmdline(
- &self,
- sess: &Session,
- lint_name: &str,
- level: Option<Level>,
- ) -> bool {
+ /// Checks the validity of lint names derived from the command line
+ pub fn check_lint_name_cmdline(&self, sess: &Session, lint_name: &str, level: Level) {
let db = match self.check_lint_name(lint_name, None) {
CheckLintNameResult::Ok(_) => None,
CheckLintNameResult::Warning(ref msg, _) => Some(sess.struct_warn(msg)),
};
if let Some(mut db) = db {
- if let Some(level) = level {
- let msg = format!(
- "requested on the command line with `{} {}`",
- match level {
- Level::Allow => "-A",
- Level::Warn => "-W",
- Level::Deny => "-D",
- Level::Forbid => "-F",
- },
- lint_name
- );
- db.note(&msg);
- }
+ let msg = format!(
+ "requested on the command line with `{} {}`",
+ match level {
+ Level::Allow => "-A",
+ Level::Warn => "-W",
+ Level::ForceWarn => "--force-warns",
+ Level::Deny => "-D",
+ Level::Forbid => "-F",
+ },
+ lint_name
+ );
+ db.note(&msg);
db.emit();
- false
- } else {
- true
}
}
self.sets.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid);
for &(ref lint_name, level) in &sess.opts.lint_opts {
- store.check_lint_name_cmdline(sess, &lint_name, Some(level));
+ store.check_lint_name_cmdline(sess, &lint_name, level);
let orig_level = level;
// If the cap is less than this specified level, e.g., if we've got
}
for lint_name in &sess.opts.force_warns {
- let valid = store.check_lint_name_cmdline(sess, lint_name, None);
- if valid {
- let lints = store
- .find_lints(lint_name)
- .unwrap_or_else(|_| bug!("A valid lint failed to produce a lint ids"));
- self.sets.force_warns.extend(&lints);
+ store.check_lint_name_cmdline(sess, lint_name, Level::ForceWarn);
+ 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));
}
}
id: LintId,
(level, src): LevelAndSource,
) {
+ let (old_level, old_src) =
+ self.sets.get_lint_level(id.lint, self.cur, Some(&specs), &self.sess);
// Setting to a non-forbid level is an error if the lint previously had
// a forbid level. Note that this is not necessarily true even with a
// `#[forbid(..)]` attribute present, as that is overriden by `--cap-lints`.
// This means that this only errors if we're truly lowering the lint
// level from forbid.
if level != Level::Forbid {
- if let (Level::Forbid, old_src) =
- self.sets.get_lint_level(id.lint, self.cur, Some(&specs), &self.sess)
- {
+ if let Level::Forbid = old_level {
// Backwards compatibility check:
//
// We used to not consider `forbid(lint_group)`
LintLevelSource::Default => false,
LintLevelSource::Node(symbol, _, _) => self.store.is_lint_group(symbol),
LintLevelSource::CommandLine(symbol, _) => self.store.is_lint_group(symbol),
- LintLevelSource::ForceWarn(_symbol) => {
- bug!("forced warn lint returned a forbid lint level")
- }
};
debug!(
"fcw_warning={:?}, specs.get(&id) = {:?}, old_src={:?}, id_name={:?}",
LintLevelSource::CommandLine(_, _) => {
diag_builder.note("`forbid` lint level was set on command line");
}
- _ => bug!("forced warn lint returned a forbid lint level"),
}
diag_builder.emit();
};
}
}
}
- specs.insert(id, (level, src));
+ if let Level::ForceWarn = old_level {
+ specs.insert(id, (old_level, old_src));
+ } else {
+ specs.insert(id, (level, src));
+ }
}
/// Pushes a list of AST lint attributes onto this context.
pub enum Level {
Allow,
Warn,
+ ForceWarn,
Deny,
Forbid,
}
match self {
Level::Allow => "allow",
Level::Warn => "warn",
+ Level::ForceWarn => "force-warns",
Level::Deny => "deny",
Level::Forbid => "forbid",
}
use std::cmp;
use crate::ich::StableHashingContext;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_errors::{DiagnosticBuilder, DiagnosticId};
use rustc_hir::HirId;
/// The provided `Level` is the level specified on the command line.
/// (The actual level may be lower due to `--cap-lints`.)
CommandLine(Symbol, Level),
-
- /// Lint is being forced to warn no matter what.
- ForceWarn(Symbol),
}
impl LintLevelSource {
LintLevelSource::Default => symbol::kw::Default,
LintLevelSource::Node(name, _, _) => name,
LintLevelSource::CommandLine(name, _) => name,
- LintLevelSource::ForceWarn(name) => name,
}
}
LintLevelSource::Default => DUMMY_SP,
LintLevelSource::Node(_, span, _) => span,
LintLevelSource::CommandLine(_, _) => DUMMY_SP,
- LintLevelSource::ForceWarn(_) => DUMMY_SP,
}
}
}
pub struct LintLevelSets {
pub list: Vec<LintSet>,
pub lint_cap: Level,
- pub force_warns: FxHashSet<LintId>,
}
#[derive(Debug)]
impl LintLevelSets {
pub fn new() -> Self {
- LintLevelSets {
- list: Vec::new(),
- lint_cap: Level::Forbid,
- force_warns: FxHashSet::default(),
- }
+ LintLevelSets { list: Vec::new(), lint_cap: Level::Forbid }
}
pub fn get_lint_level(
aux: Option<&FxHashMap<LintId, LevelAndSource>>,
sess: &Session,
) -> LevelAndSource {
- // Check whether we should always warn
- if self.force_warns.contains(&LintId::of(lint)) {
- return (Level::Warn, LintLevelSource::ForceWarn(Symbol::intern(lint.name)));
- }
-
let (level, mut src) = self.get_lint_id_level(LintId::of(lint), idx, aux);
// If `level` is none then we actually assume the default level for this
impl<'a> HashStable<StableHashingContext<'a>> for LintLevelMap {
#[inline]
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
- let LintLevelMap { ref sets, ref id_to_set, .. } = *self;
+ let LintLevelMap { ref sets, ref id_to_set } = *self;
id_to_set.hash_stable(hcx, hasher);
- let LintLevelSets { ref list, lint_cap, .. } = *sets;
+ let LintLevelSets { ref list, lint_cap } = *sets;
lint_cap.hash_stable(hcx, hasher);
return;
}
}
- (Level::Warn, Some(span)) => sess.struct_span_warn(span, ""),
- (Level::Warn, None) => sess.struct_warn(""),
+ (Level::Warn | Level::ForceWarn, Some(span)) => sess.struct_span_warn(span, ""),
+ (Level::Warn | Level::ForceWarn, None) => sess.struct_warn(""),
(Level::Deny | Level::Forbid, Some(span)) => sess.struct_span_err(span, ""),
(Level::Deny | Level::Forbid, None) => sess.struct_err(""),
};
Level::Deny => "-D",
Level::Forbid => "-F",
Level::Allow => "-A",
+ Level::ForceWarn => "--force-warns",
};
let hyphen_case_lint_name = name.replace("_", "-");
if lint_flag_val.as_str() == name {
);
}
}
- LintLevelSource::ForceWarn(_) => {
- sess.diag_note_once(
- &mut err,
- DiagnosticMessageId::from(lint),
- "warning forced by `force-warns` commandline option",
- );
- }
}
err.code(DiagnosticId::Lint { name, has_future_breakage });
LL | fn foo(x: &Foo) {}
| ^^^- help: indicate the anonymous lifetime: `<'_>`
|
- = note: warning forced by `force-warns` commandline option
+ = note: requested on the command line with `--force-warns elided-lifetimes-in-paths`
warning: 1 warning emitted
| |
| attempt to divide `1_i32` by zero
|
- = note: warning forced by `force-warns` commandline option
+ = note: requested on the command line with `--force-warns const-err`
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
LL | fn dead_function() {}
| ^^^^^^^^^^^^^
|
- = note: warning forced by `force-warns` commandline option
+ = note: requested on the command line with `--force-warns dead-code`
warning: 1 warning emitted
| |
| attempt to divide `1_i32` by zero
|
- = note: warning forced by `force-warns` commandline option
+ = note: requested on the command line with `--force-warns const-err`
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
LL | fn dead_function() {}
| ^^^^^^^^^^^^^
|
- = note: warning forced by `force-warns` commandline option
+ = note: requested on the command line with `--force-warns dead-code`
warning: 1 warning emitted
LL | pub fn FUNCTION() {}
| ^^^^^^^^ help: convert the identifier to snake case: `function`
|
- = note: warning forced by `force-warns` commandline option
+ = note: `--force-warns non-snake-case` implied by `--force-warns nonstandard-style`
warning: 1 warning emitted
LL | pub fn function(_x: Box<SomeTrait>) {}
| ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
|
- = note: warning forced by `force-warns` commandline option
+ = note: requested on the command line with `--force-warns bare-trait-objects`
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
LL | pub fn function(_x: Box<SomeTrait>) {}
| ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
|
- = note: warning forced by `force-warns` commandline option
+ = note: `--force-warns bare-trait-objects` implied by `--force-warns rust-2018-idioms`
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
LL | pub fn function(_x: Box<SomeTrait>) {}
| ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
|
- = note: warning forced by `force-warns` commandline option
+ = note: `--force-warns bare-trait-objects` implied by `--force-warns rust-2018-idioms`
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>