about summary refs log tree commit diff
path: root/src/librustc/lint
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2016-10-06 04:56:13 -0400
committerNiko Matsakis <niko@alum.mit.edu>2016-11-01 14:07:45 -0400
commit75bc8bfa922e533f111e54b0d841d85d61c7f317 (patch)
treef4aa45bf9e42f4a7b94accb6d06274aa1feaab05 /src/librustc/lint
parentbd5fa7532d9f9944b6347624553f420bd7c89132 (diff)
downloadrust-75bc8bfa922e533f111e54b0d841d85d61c7f317.tar.gz
rust-75bc8bfa922e533f111e54b0d841d85d61c7f317.zip
introduce EarlyLint type
For now, this type just replaces a tuple, but it will eventually grow
the ability to carry more structured information.
Diffstat (limited to 'src/librustc/lint')
-rw-r--r--src/librustc/lint/context.rs61
-rw-r--r--src/librustc/lint/mod.rs2
2 files changed, 52 insertions, 11 deletions
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 20463f42d3b..bcc8384dd0e 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -38,6 +38,7 @@ use util::nodemap::FnvHashMap;
 use std::cmp;
 use std::default::Default as StdDefault;
 use std::mem;
+use std::fmt;
 use syntax::attr;
 use syntax::parse::token::InternedString;
 use syntax::ast;
@@ -80,6 +81,41 @@ pub struct LintStore {
     lint_cap: Option<Level>,
 }
 
+/// When you call `add_lint` on the session, you wind up storing one
+/// of these, which records a "potential lint" at a particular point.
+pub struct EarlyLint {
+    /// what lint is this? (e.g., `dead_code`)
+    pub id: LintId,
+
+    /// the span where the lint will be reported at
+    pub span: Span,
+
+    /// the main message
+    pub msg: String,
+}
+
+impl fmt::Debug for EarlyLint {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("EarlyLint")
+            .field("id", &self.id)
+            .field("span", &self.span)
+            .field("msg", &self.msg)
+            .finish()
+    }
+}
+
+impl EarlyLint {
+    pub fn new(id: LintId, span: Span, msg: String) -> Self {
+        EarlyLint { id: id, span: span, msg: msg }
+    }
+
+    pub fn matches(&self, other: &EarlyLint) -> bool {
+        self.id == other.id && self.span == other.span && self.msg == other.msg
+    }
+}
+
+
+
 /// Extra information for a future incompatibility lint. See the call
 /// to `register_future_incompatible` in `librustc_lint/lib.rs` for
 /// guidelines.
@@ -514,6 +550,11 @@ pub trait LintContext: Sized {
         self.lookup_and_emit(lint, Some(span), msg);
     }
 
+    fn early_lint(&self, early_lint: EarlyLint) {
+        let mut err = self.struct_span_lint(early_lint.id.lint, early_lint.span, &early_lint.msg);
+        err.emit();
+    }
+
     fn struct_span_lint(&self,
                         lint: &'static Lint,
                         span: Span,
@@ -1065,8 +1106,8 @@ impl<'a, 'b, 'tcx, 'v> hir_visit::Visitor<'v> for IdVisitor<'a, 'b, 'tcx> {
     fn visit_id(&mut self, id: ast::NodeId) {
         if let Some(lints) = self.cx.sess().lints.borrow_mut().remove(&id) {
             debug!("LateContext::visit_id: id={:?} lints={:?}", id, lints);
-            for (lint_id, span, msg) in lints {
-                self.cx.span_lint(lint_id.lint, span, &msg[..])
+            for early_lint in lints {
+                self.cx.early_lint(early_lint);
             }
         }
     }
@@ -1211,10 +1252,10 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // If we missed any lints added to the session, then there's a bug somewhere
     // in the iteration code.
     for (id, v) in tcx.sess.lints.borrow().iter() {
-        for &(lint, span, ref msg) in v {
-            span_bug!(span,
-                      "unprocessed lint {} at {}: {}",
-                      lint.to_string(), tcx.map.node_to_string(*id), *msg)
+        for early_lint in v {
+            span_bug!(early_lint.span,
+                      "unprocessed lint {:?} at {}",
+                      early_lint, tcx.map.node_to_string(*id));
         }
     }
 
@@ -1229,8 +1270,8 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
     cx.with_lint_attrs(&krate.attrs, |cx| {
         // Lints may be assigned to the whole crate.
         if let Some(lints) = cx.sess.lints.borrow_mut().remove(&ast::CRATE_NODE_ID) {
-            for (lint_id, span, msg) in lints {
-                cx.span_lint(lint_id.lint, span, &msg[..])
+            for early_lint in lints {
+                cx.early_lint(early_lint);
             }
         }
 
@@ -1249,8 +1290,8 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
     // If we missed any lints added to the session, then there's a bug somewhere
     // in the iteration code.
     for (_, v) in sess.lints.borrow().iter() {
-        for &(lint, span, ref msg) in v {
-            span_bug!(span, "unprocessed lint {}: {}", lint.to_string(), *msg)
+        for early_lint in v {
+            span_bug!(early_lint.span, "unprocessed lint {:?}", early_lint);
         }
     }
 }
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 7eea6a2fcf2..0e11546e643 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -41,7 +41,7 @@ use hir;
 
 pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
                         raw_emit_lint, check_crate, check_ast_crate, gather_attrs,
-                        raw_struct_lint, FutureIncompatibleInfo};
+                        raw_struct_lint, FutureIncompatibleInfo, EarlyLint};
 
 /// Specification of a single lint.
 #[derive(Copy, Clone, Debug)]