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 where
F: FnOnce(&mut Self), 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.check_id(id);
self.enter_attrs(attrs); self.enter_attrs(attrs);
f(self); f(self);

View file

@ -29,7 +29,7 @@ fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> LintLevelMap {
let mut builder = LintLevelMapBuilder { levels, tcx, store }; let mut builder = LintLevelMapBuilder { levels, tcx, store };
let krate = tcx.hir().krate(); 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); builder.levels.register_id(hir::CRATE_HIR_ID);
for macro_def in krate.exported_macros { for macro_def in krate.exported_macros {
builder.levels.register_id(macro_def.hir_id); builder.levels.register_id(macro_def.hir_id);
@ -109,7 +109,12 @@ impl<'s> LintLevelsBuilder<'s> {
/// `#[allow]` /// `#[allow]`
/// ///
/// Don't forget to call `pop`! /// 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 mut specs = FxHashMap::default();
let sess = self.sess; let sess = self.sess;
let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input"); 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() { for (id, &(level, ref src)) in specs.iter() {
if level == Level::Forbid { if level == Level::Forbid {
continue; continue;
@ -449,7 +488,8 @@ impl LintLevelMapBuilder<'_, '_> {
where where
F: FnOnce(&mut Self), 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 { if push.changed {
self.levels.register_id(id); self.levels.register_id(id);
} }

View file

@ -8,20 +8,23 @@ use std::ops::Deref;
declare_lint! { declare_lint! {
pub NON_ASCII_IDENTS, pub NON_ASCII_IDENTS,
Allow, Allow,
"detects non-ASCII identifiers" "detects non-ASCII identifiers",
crate_level_only
} }
declare_lint! { declare_lint! {
pub UNCOMMON_CODEPOINTS, pub UNCOMMON_CODEPOINTS,
Warn, Warn,
"detects uncommon Unicode codepoints in identifiers" "detects uncommon Unicode codepoints in identifiers",
crate_level_only
} }
// FIXME: Change this to warn. // FIXME: Change this to warn.
declare_lint! { declare_lint! {
pub CONFUSABLE_IDENTS, pub CONFUSABLE_IDENTS,
Allow, 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]); 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`. /// `Some` if this lint is feature gated, otherwise `None`.
pub feature_gate: Option<Symbol>, pub feature_gate: Option<Symbol>,
pub crate_level_only: bool,
} }
/// Extra information for a future incompatibility lint. /// Extra information for a future incompatibility lint.
@ -111,6 +113,7 @@ impl Lint {
report_in_external_macro: false, report_in_external_macro: false,
future_incompatible: None, future_incompatible: None,
feature_gate: None, feature_gate: None,
crate_level_only: false,
} }
} }
@ -336,6 +339,7 @@ macro_rules! declare_tool_lint {
future_incompatible: None, future_incompatible: None,
is_plugin: true, is_plugin: true,
feature_gate: None, 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>", reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
edition: None, edition: None,
}; };
crate_level_only
} }
declare_lint! { declare_lint! {
@ -75,7 +76,8 @@ declare_lint! {
declare_lint! { declare_lint! {
pub UNUSED_CRATE_DEPENDENCIES, pub UNUSED_CRATE_DEPENDENCIES,
Allow, Allow,
"crate dependencies that are never used" "crate dependencies that are never used",
crate_level_only
} }
declare_lint! { declare_lint! {
@ -166,7 +168,8 @@ declare_lint! {
declare_lint! { declare_lint! {
pub UNKNOWN_CRATE_TYPES, pub UNKNOWN_CRATE_TYPES,
Deny, Deny,
"unknown crate type found in `#[crate_type]` directive" "unknown crate type found in `#[crate_type]` directive",
crate_level_only
} }
declare_lint! { declare_lint! {
@ -339,7 +342,8 @@ declare_lint! {
declare_lint! { declare_lint! {
pub ELIDED_LIFETIMES_IN_PATHS, pub ELIDED_LIFETIMES_IN_PATHS,
Allow, Allow,
"hidden lifetime parameters in types are deprecated" "hidden lifetime parameters in types are deprecated",
crate_level_only
} }
declare_lint! { declare_lint! {
@ -459,6 +463,7 @@ declare_lint! {
reference: "issue #52234 <https://github.com/rust-lang/rust/issues/52234>", reference: "issue #52234 <https://github.com/rust-lang/rust/issues/52234>",
edition: None, edition: None,
}; };
crate_level_only
} }
declare_lint! { declare_lint! {

View file

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