From f633dd385f7b064b4d9eb77e77a4836dc65ca82c Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Sat, 13 Jun 2020 09:58:24 +0800 Subject: [PATCH] Implement crate level only lints checking. --- src/librustc_lint/early.rs | 3 +- src/librustc_lint/levels.rs | 46 +++++++++++++- src/librustc_lint/non_ascii_idents.rs | 9 ++- src/librustc_session/lint.rs | 4 ++ src/librustc_session/lint/builtin.rs | 11 +++- src/test/ui/issues/issue-48508.rs | 2 +- src/test/ui/lint/crate_level_only_lint.rs | 22 +++++++ src/test/ui/lint/crate_level_only_lint.stderr | 62 +++++++++++++++++++ 8 files changed, 148 insertions(+), 11 deletions(-) create mode 100644 src/test/ui/lint/crate_level_only_lint.rs create mode 100644 src/test/ui/lint/crate_level_only_lint.stderr diff --git a/src/librustc_lint/early.rs b/src/librustc_lint/early.rs index 06987ffa3d569..d891466611ad3 100644 --- a/src/librustc_lint/early.rs +++ b/src/librustc_lint/early.rs @@ -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); diff --git a/src/librustc_lint/levels.rs b/src/librustc_lint/levels.rs index 05e7c9a0c780d..f875e2750a5c5 100644 --- a/src/librustc_lint/levels.rs +++ b/src/librustc_lint/levels.rs @@ -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); } diff --git a/src/librustc_lint/non_ascii_idents.rs b/src/librustc_lint/non_ascii_idents.rs index ad02b2637d22f..064b0255397ce 100644 --- a/src/librustc_lint/non_ascii_idents.rs +++ b/src/librustc_lint/non_ascii_idents.rs @@ -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]); diff --git a/src/librustc_session/lint.rs b/src/librustc_session/lint.rs index ffb4579309075..0dcbee08abea1 100644 --- a/src/librustc_session/lint.rs +++ b/src/librustc_session/lint.rs @@ -88,6 +88,8 @@ pub struct Lint { /// `Some` if this lint is feature gated, otherwise `None`. pub feature_gate: Option, + + 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, }; ); } diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs index bb0d6e1a47ead..e3444bb0e54ce 100644 --- a/src/librustc_session/lint/builtin.rs +++ b/src/librustc_session/lint/builtin.rs @@ -17,6 +17,7 @@ declare_lint! { reference: "issue #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 ", edition: None, }; + crate_level_only } declare_lint! { diff --git a/src/test/ui/issues/issue-48508.rs b/src/test/ui/issues/issue-48508.rs index 87965c204ada7..8dc9351260ebc 100644 --- a/src/test/ui/issues/issue-48508.rs +++ b/src/test/ui/issues/issue-48508.rs @@ -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; diff --git a/src/test/ui/lint/crate_level_only_lint.rs b/src/test/ui/lint/crate_level_only_lint.rs new file mode 100644 index 0000000000000..d9673faa2142e --- /dev/null +++ b/src/test/ui/lint/crate_level_only_lint.rs @@ -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() { +} diff --git a/src/test/ui/lint/crate_level_only_lint.stderr b/src/test/ui/lint/crate_level_only_lint.stderr new file mode 100644 index 0000000000000..8fb06df2a481a --- /dev/null +++ b/src/test/ui/lint/crate_level_only_lint.stderr @@ -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 +