]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/lint/context.rs
added function to check if lints belong to an external macro
[rust.git] / src / librustc / lint / context.rs
index 824930a7eb00007766e052d0992bbaf0ff494032..a5517e85d444241348e14964e84ac89d575bdd94 100644 (file)
@@ -29,7 +29,7 @@
 use std::slice;
 use rustc_data_structures::sync::{RwLock, ReadGuard};
 use lint::{EarlyLintPassObject, LateLintPassObject};
-use lint::{Level, Lint, LintId, LintPass, LintBuffer};
+use lint::{self, Level, Lint, LintId, LintPass, LintBuffer};
 use lint::builtin::BuiltinLintDiagnostics;
 use lint::levels::{LintLevelSets, LintLevelsBuilder};
 use middle::privacy::AccessLevels;
@@ -131,8 +131,8 @@ pub enum CheckLintNameResult<'a> {
     /// Lint doesn't exist
     NoLint,
     /// The lint is either renamed or removed. This is the warning
-    /// message.
-    Warning(String),
+    /// message, and an optional new name (`None` if removed).
+    Warning(String, Option<String>),
 }
 
 impl LintStore {
@@ -178,10 +178,10 @@ fn push_pass<P: LintPass + ?Sized + 'static>(&mut self,
                                         sess: Option<&Session>,
                                         from_plugin: bool,
                                         pass: &Box<P>) {
-        for &lint in pass.get_lints() {
-            self.lints.push((*lint, from_plugin));
+        for lint in pass.get_lints() {
+            self.lints.push((lint, from_plugin));
 
-            let id = LintId::of(*lint);
+            let id = LintId::of(lint);
             if self.by_name.insert(lint.name_lower(), Id(id)).is_some() {
                 let msg = format!("duplicate specification of lint {}", lint.name_lower());
                 match (sess, from_plugin) {
@@ -280,7 +280,7 @@ pub fn check_lint_name_cmdline(&self,
                                    level: Level) {
         let db = match self.check_lint_name(lint_name) {
             CheckLintNameResult::Ok(_) => None,
-            CheckLintNameResult::Warning(ref msg) => {
+            CheckLintNameResult::Warning(ref msg, _) => {
                 Some(sess.struct_warn(msg))
             },
             CheckLintNameResult::NoLint => {
@@ -313,12 +313,14 @@ pub fn check_lint_name(&self, lint_name: &str) -> CheckLintNameResult {
         match self.by_name.get(lint_name) {
             Some(&Renamed(ref new_name, _)) => {
                 CheckLintNameResult::Warning(
-                    format!("lint {} has been renamed to {}", lint_name, new_name)
+                    format!("lint `{}` has been renamed to `{}`", lint_name, new_name),
+                    Some(new_name.to_owned())
                 )
             },
             Some(&Removed(ref reason)) => {
                 CheckLintNameResult::Warning(
-                    format!("lint {} has been removed: {}", lint_name, reason)
+                    format!("lint `{}` has been removed: `{}`", lint_name, reason),
+                    None
                 )
             },
             None => {
@@ -466,7 +468,14 @@ fn lookup<S: Into<MultiSpan>>(&self,
 
     /// Emit a lint at the appropriate level, for a particular span.
     fn span_lint<S: Into<MultiSpan>>(&self, lint: &'static Lint, span: S, msg: &str) {
-        self.lookup_and_emit(lint, Some(span), msg);
+        match self.lints().future_incompatible(LintId::of(lint)) {
+            Some(_) => self.lookup_and_emit(lint, Some(span), msg),
+            None => {
+                if !lint::in_external_macro(lint, span) {
+                    self.lookup_and_emit(lint, Some(span), msg);
+                }
+            }
+        }
     }
 
     fn struct_span_lint<S: Into<MultiSpan>>(&self,