Implement crate level only lints checking.

This commit is contained in:
Charles Lew 2020-06-13 09:58:24 +08:00
parent 59493917be
commit f633dd385f
8 changed files with 148 additions and 11 deletions

View file

@ -55,7 +55,8 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
where
F: FnOnce(&mut Self),
{
let push = self.context.builder.push(attrs, &self.context.lint_store);
let is_crate_node = id == ast::CRATE_NODE_ID;
let push = self.context.builder.push(attrs, &self.context.lint_store, is_crate_node);
self.check_id(id);
self.enter_attrs(attrs);
f(self);

View file

@ -29,7 +29,7 @@ fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> LintLevelMap {
let mut builder = LintLevelMapBuilder { levels, tcx, store };
let krate = tcx.hir().krate();
let push = builder.levels.push(&krate.item.attrs, &store);
let push = builder.levels.push(&krate.item.attrs, &store, true);
builder.levels.register_id(hir::CRATE_HIR_ID);
for macro_def in krate.exported_macros {
builder.levels.register_id(macro_def.hir_id);
@ -109,7 +109,12 @@ impl<'s> LintLevelsBuilder<'s> {
/// `#[allow]`
///
/// Don't forget to call `pop`!
pub fn push(&mut self, attrs: &[ast::Attribute], store: &LintStore) -> BuilderPush {
pub fn push(
&mut self,
attrs: &[ast::Attribute],
store: &LintStore,
is_crate_node: bool,
) -> BuilderPush {
let mut specs = FxHashMap::default();
let sess = self.sess;
let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input");
@ -333,6 +338,40 @@ impl<'s> LintLevelsBuilder<'s> {
}
}
if !is_crate_node {
for (id, &(level, ref src)) in specs.iter() {
if !id.lint.crate_level_only {
continue;
}
let (lint_attr_name, lint_attr_span) = match *src {
LintSource::Node(name, span, _) => (name, span),
_ => continue,
};
let lint = builtin::UNUSED_ATTRIBUTES;
let (lint_level, lint_src) =
self.sets.get_lint_level(lint, self.cur, Some(&specs), self.sess);
struct_lint_level(
self.sess,
lint,
lint_level,
lint_src,
Some(lint_attr_span.into()),
|lint| {
let mut db = lint.build(&format!(
"{}({}) is ignored unless specified at crate level",
level.as_str(),
lint_attr_name
));
db.emit();
},
);
// don't set a separate error for every lint in the group
break;
}
}
for (id, &(level, ref src)) in specs.iter() {
if level == Level::Forbid {
continue;
@ -449,7 +488,8 @@ impl LintLevelMapBuilder<'_, '_> {
where
F: FnOnce(&mut Self),
{
let push = self.levels.push(attrs, self.store);
let is_crate_hir = id == hir::CRATE_HIR_ID;
let push = self.levels.push(attrs, self.store, is_crate_hir);
if push.changed {
self.levels.register_id(id);
}

View file

@ -8,20 +8,23 @@ use std::ops::Deref;
declare_lint! {
pub NON_ASCII_IDENTS,
Allow,
"detects non-ASCII identifiers"
"detects non-ASCII identifiers",
crate_level_only
}
declare_lint! {
pub UNCOMMON_CODEPOINTS,
Warn,
"detects uncommon Unicode codepoints in identifiers"
"detects uncommon Unicode codepoints in identifiers",
crate_level_only
}
// FIXME: Change this to warn.
declare_lint! {
pub CONFUSABLE_IDENTS,
Allow,
"detects visually confusable pairs between identifiers"
"detects visually confusable pairs between identifiers",
crate_level_only
}
declare_lint_pass!(NonAsciiIdents => [NON_ASCII_IDENTS, UNCOMMON_CODEPOINTS, CONFUSABLE_IDENTS]);

View file

@ -88,6 +88,8 @@ pub struct Lint {
/// `Some` if this lint is feature gated, otherwise `None`.
pub feature_gate: Option<Symbol>,
pub crate_level_only: bool,
}
/// Extra information for a future incompatibility lint.
@ -111,6 +113,7 @@ impl Lint {
report_in_external_macro: false,
future_incompatible: None,
feature_gate: None,
crate_level_only: false,
}
}
@ -336,6 +339,7 @@ macro_rules! declare_tool_lint {
future_incompatible: None,
is_plugin: true,
feature_gate: None,
crate_level_only: false,
};
);
}

View file

@ -17,6 +17,7 @@ declare_lint! {
reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
edition: None,
};
crate_level_only
}
declare_lint! {
@ -75,7 +76,8 @@ declare_lint! {
declare_lint! {
pub UNUSED_CRATE_DEPENDENCIES,
Allow,
"crate dependencies that are never used"
"crate dependencies that are never used",
crate_level_only
}
declare_lint! {
@ -166,7 +168,8 @@ declare_lint! {
declare_lint! {
pub UNKNOWN_CRATE_TYPES,
Deny,
"unknown crate type found in `#[crate_type]` directive"
"unknown crate type found in `#[crate_type]` directive",
crate_level_only
}
declare_lint! {
@ -339,7 +342,8 @@ declare_lint! {
declare_lint! {
pub ELIDED_LIFETIMES_IN_PATHS,
Allow,
"hidden lifetime parameters in types are deprecated"
"hidden lifetime parameters in types are deprecated",
crate_level_only
}
declare_lint! {
@ -459,6 +463,7 @@ declare_lint! {
reference: "issue #52234 <https://github.com/rust-lang/rust/issues/52234>",
edition: None,
};
crate_level_only
}
declare_lint! {

View file

@ -11,7 +11,7 @@
// ignore-asmjs wasm2js does not support source maps yet
#![feature(non_ascii_idents)]
#[allow(uncommon_codepoints)]
#![allow(uncommon_codepoints)]
#[path = "issue-48508-aux.rs"]
mod other_file;

View file

@ -0,0 +1,22 @@
#![deny(uncommon_codepoints, unused_attributes)]
mod foo {
#![allow(uncommon_codepoints)]
//~^ ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
#[allow(uncommon_codepoints)]
//~^ ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
const BAR: f64 = 0.000001;
}
#[allow(uncommon_codepoints)]
//~^ ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
fn main() {
}

View file

@ -0,0 +1,62 @@
error: allow(uncommon_codepoints) is ignored unless specified at crate level
--> $DIR/crate_level_only_lint.rs:4:10
|
LL | #![allow(uncommon_codepoints)]
| ^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/crate_level_only_lint.rs:1:30
|
LL | #![deny(uncommon_codepoints, unused_attributes)]
| ^^^^^^^^^^^^^^^^^
error: allow(uncommon_codepoints) is ignored unless specified at crate level
--> $DIR/crate_level_only_lint.rs:9:9
|
LL | #[allow(uncommon_codepoints)]
| ^^^^^^^^^^^^^^^^^^^
error: allow(uncommon_codepoints) is ignored unless specified at crate level
--> $DIR/crate_level_only_lint.rs:17:9
|
LL | #[allow(uncommon_codepoints)]
| ^^^^^^^^^^^^^^^^^^^
error: allow(uncommon_codepoints) is ignored unless specified at crate level
--> $DIR/crate_level_only_lint.rs:4:10
|
LL | #![allow(uncommon_codepoints)]
| ^^^^^^^^^^^^^^^^^^^
error: allow(uncommon_codepoints) is ignored unless specified at crate level
--> $DIR/crate_level_only_lint.rs:9:9
|
LL | #[allow(uncommon_codepoints)]
| ^^^^^^^^^^^^^^^^^^^
error: allow(uncommon_codepoints) is ignored unless specified at crate level
--> $DIR/crate_level_only_lint.rs:17:9
|
LL | #[allow(uncommon_codepoints)]
| ^^^^^^^^^^^^^^^^^^^
error: allow(uncommon_codepoints) is ignored unless specified at crate level
--> $DIR/crate_level_only_lint.rs:4:10
|
LL | #![allow(uncommon_codepoints)]
| ^^^^^^^^^^^^^^^^^^^
error: allow(uncommon_codepoints) is ignored unless specified at crate level
--> $DIR/crate_level_only_lint.rs:9:9
|
LL | #[allow(uncommon_codepoints)]
| ^^^^^^^^^^^^^^^^^^^
error: allow(uncommon_codepoints) is ignored unless specified at crate level
--> $DIR/crate_level_only_lint.rs:17:9
|
LL | #[allow(uncommon_codepoints)]
| ^^^^^^^^^^^^^^^^^^^
error: aborting due to 9 previous errors