rustc: Fix unknown_lints next to an unknown lint

The lint refactoring in #43522 didn't account for `#[allow(unknown_lints)]`
happening at the same node as an unknown lint itself, so this commit updates the
handling to ensure that the local set of lint configuration being built is
queried before looking at the chain of lint levels.

Closes #43809
This commit is contained in:
Alex Crichton 2017-08-13 05:37:24 -07:00
parent f774bced50
commit 8b2bdc56d0
2 changed files with 62 additions and 19 deletions

View File

@ -83,10 +83,13 @@ fn process_command_line(&mut self, sess: &Session) {
});
}
fn get_lint_level(&self, lint: &'static Lint, idx: u32)
fn get_lint_level(&self,
lint: &'static Lint,
idx: u32,
aux: Option<&FxHashMap<LintId, (Level, LintSource)>>)
-> (Level, LintSource)
{
let (level, mut src) = self.get_lint_id_level(LintId::of(lint), idx);
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
// lint.
@ -97,7 +100,9 @@ fn get_lint_level(&self, lint: &'static Lint, idx: u32)
// `allow(warnings)` in scope then we want to respect that instead.
if level == Level::Warn {
let (warnings_level, warnings_src) =
self.get_lint_id_level(LintId::of(lint::builtin::WARNINGS), idx);
self.get_lint_id_level(LintId::of(lint::builtin::WARNINGS),
idx,
aux);
if let Some(configured_warning_level) = warnings_level {
if configured_warning_level != Level::Warn {
level = configured_warning_level;
@ -112,9 +117,17 @@ fn get_lint_level(&self, lint: &'static Lint, idx: u32)
return (level, src)
}
fn get_lint_id_level(&self, id: LintId, mut idx: u32)
fn get_lint_id_level(&self,
id: LintId,
mut idx: u32,
aux: Option<&FxHashMap<LintId, (Level, LintSource)>>)
-> (Option<Level>, LintSource)
{
if let Some(specs) = aux {
if let Some(&(level, src)) = specs.get(&id) {
return (Some(level), src)
}
}
loop {
match self.list[idx as usize] {
LintSet::CommandLine { ref specs } => {
@ -212,21 +225,35 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
specs.insert(*id, (level, src));
}
}
_ if !self.warn_about_weird_lints => {}
CheckLintNameResult::Warning(ref msg) => {
if self.warn_about_weird_lints {
self.struct_lint(builtin::RENAMED_AND_REMOVED_LINTS,
Some(li.span.into()),
msg)
.emit();
}
let lint = builtin::RENAMED_AND_REMOVED_LINTS;
let (level, src) = self.sets.get_lint_level(lint,
self.cur,
Some(&specs));
lint::struct_lint_level(self.sess,
lint,
level,
src,
Some(li.span.into()),
msg)
.emit();
}
CheckLintNameResult::NoLint => {
if self.warn_about_weird_lints {
self.struct_lint(builtin::UNKNOWN_LINTS,
Some(li.span.into()),
&format!("unknown lint: `{}`", name))
.emit();
}
let lint = builtin::UNKNOWN_LINTS;
let (level, src) = self.sets.get_lint_level(lint,
self.cur,
Some(&specs));
let msg = format!("unknown lint: `{}`", name);
lint::struct_lint_level(self.sess,
lint,
level,
src,
Some(li.span.into()),
&msg)
.emit();
}
}
}
@ -236,7 +263,7 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
if level == Level::Forbid {
continue
}
let forbid_src = match self.sets.get_lint_id_level(*id, self.cur) {
let forbid_src = match self.sets.get_lint_id_level(*id, self.cur, None) {
(Some(Level::Forbid), src) => src,
_ => continue,
};
@ -298,7 +325,7 @@ pub fn struct_lint(&self,
msg: &str)
-> DiagnosticBuilder<'a>
{
let (level, src) = self.sets.get_lint_level(lint, self.cur);
let (level, src) = self.sets.get_lint_level(lint, self.cur, None);
lint::struct_lint_level(self.sess, lint, level, src, span, msg)
}
@ -337,7 +364,7 @@ pub fn level_and_source(&self, lint: &'static Lint, id: HirId)
-> Option<(Level, LintSource)>
{
self.id_to_set.get(&id).map(|idx| {
self.sets.get_lint_level(lint, *idx)
self.sets.get_lint_level(lint, *idx, None)
})
}
}

View File

@ -0,0 +1,16 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: -D warnings -D unknown-lints
#![allow(unknown_lints)]
#![allow(random_lint_name)]
fn main() {}