]> git.lizzy.rs Git - rust.git/commitdiff
Support #[allow] etc logic on a per macro level
authorest31 <MTest31@outlook.com>
Fri, 12 May 2017 06:10:52 +0000 (08:10 +0200)
committerest31 <MTest31@outlook.com>
Sat, 13 May 2017 14:02:29 +0000 (16:02 +0200)
This commit extends the current unused macro linter
to support directives like #[allow(unused_macros)]
or #[deny(unused_macros)] directly next to the macro
definition, or in one of the modules the macro is
inside. Before, we only supported such directives
at a per crate level, due to the crate's NodeId
being passed to session.add_lint.

We also had to implement handling of the macro's
NodeId in the lint visitor.

src/librustc/lint/context.rs
src/librustc_plugin/registry.rs
src/librustc_resolve/macros.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/tt/macro_rules.rs

index 6f3e84247f797ddbfdadfd43ffa73d341fbedff7..172b74d539334a5d9278feeea33b726e4b9bd6ac 100644 (file)
@@ -49,6 +49,7 @@
 use hir::def_id::LOCAL_CRATE;
 use hir::intravisit as hir_visit;
 use syntax::visit as ast_visit;
+use syntax::tokenstream::ThinTokenStream;
 
 /// Information about the registered lints.
 ///
@@ -1125,6 +1126,13 @@ fn visit_path_list_item(&mut self, prefix: &'a ast::Path, item: &'a ast::PathLis
     fn visit_attribute(&mut self, attr: &'a ast::Attribute) {
         run_lints!(self, check_attribute, early_passes, attr);
     }
+
+    fn visit_mac_def(&mut self, _mac: &'a ThinTokenStream, id: ast::NodeId) {
+        let lints = self.sess.lints.borrow_mut().take(id);
+        for early_lint in lints {
+            self.early_lint(&early_lint);
+        }
+    }
 }
 
 enum CheckLintNameResult {
index cdde56f5f634be75a2d0917a5a1885bf59606e2d..3027489d65be2ea1f955e5e3c5e1c8e611b66280 100644 (file)
@@ -103,7 +103,8 @@ pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxEx
         }
         self.syntax_exts.push((name, match extension {
             NormalTT(ext, _, allow_internal_unstable) => {
-                NormalTT(ext, Some(self.krate_span), allow_internal_unstable)
+                let nid = ast::CRATE_NODE_ID;
+                NormalTT(ext, Some((nid, self.krate_span)), allow_internal_unstable)
             }
             IdentTT(ext, _, allow_internal_unstable) => {
                 IdentTT(ext, Some(self.krate_span), allow_internal_unstable)
index 29ca163b0b4b7b02b6b12577ccf411718ddfc460..f6155c6cafdea1256c7d452f1900a3bc2a3f022c 100644 (file)
@@ -305,17 +305,14 @@ fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, forc
 
     fn check_unused_macros(&self) {
         for (did, _) in self.unused_macros.iter().filter(|&(_, b)| *b) {
-            let span = match *self.macro_map[did] {
-                           SyntaxExtension::NormalTT(_, sp, _) => sp,
-                           SyntaxExtension::IdentTT(_, sp, _) => sp,
+            let id_span = match *self.macro_map[did] {
+                           SyntaxExtension::NormalTT(_, isp, _) => isp,
                            _ => None
                        };
-            if let Some(span) = span {
+            if let Some((id, span)) = id_span {
                 let lint = lint::builtin::UNUSED_MACROS;
-                let msg = "unused macro".to_string();
-                // We are using CRATE_NODE_ID here even though its inaccurate, as we
-                // sadly don't have the NodeId of the macro definition.
-                self.session.add_lint(lint, ast::CRATE_NODE_ID, span, msg);
+                let msg = "unused macro definition".to_string();
+                self.session.add_lint(lint, id, span, msg);
             } else {
                 bug!("attempted to create unused macro error, but span not available");
             }
index b0253ec3905c931f96374c00c51fa48d61166ef5..86202f77dbf8afa04da0ae16dd3ff5d14ac64f32 100644 (file)
@@ -535,7 +535,7 @@ pub enum SyntaxExtension {
     ///
     /// The `bool` dictates whether the contents of the macro can
     /// directly use `#[unstable]` things (true == yes).
-    NormalTT(Box<TTMacroExpander>, Option<Span>, bool),
+    NormalTT(Box<TTMacroExpander>, Option<(ast::NodeId, Span)>, bool),
 
     /// A function-like syntax extension that has an extra ident before
     /// the block.
index a8aa103f80a8e4a7c0f150d59ebfd2a427cd7517..75dd09f23115e507b9cf9eb42b16b5057b136dd9 100644 (file)
@@ -469,7 +469,7 @@ fn expand_bang_invoc(&mut self, invoc: Invocation, ext: Rc<SyntaxExtension>) ->
                     call_site: span,
                     callee: NameAndSpan {
                         format: MacroBang(Symbol::intern(&format!("{}", path))),
-                        span: exp_span,
+                        span: exp_span.map(|(_, s)| s),
                         allow_internal_unstable: allow_internal_unstable,
                     },
                 });
index f959ccc989e2e9e9d55643966f0fe4648b8bd17b..0c787dcbecb9a8d207cdc0f3872fe53906d52345 100644 (file)
@@ -252,7 +252,11 @@ pub fn compile(sess: &ParseSess, features: &RefCell<Features>, def: &ast::Item)
         valid: valid,
     });
 
-    NormalTT(exp, Some(def.span), attr::contains_name(&def.attrs, "allow_internal_unstable"))
+    NormalTT(
+             exp,
+             Some((def.id, def.span)),
+             attr::contains_name(&def.attrs, "allow_internal_unstable")
+    )
 }
 
 fn check_lhs_nt_follows(sess: &ParseSess,