about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/Cargo.lock1
-rw-r--r--src/librustc/lint/context.rs28
-rw-r--r--src/librustc/lint/mod.rs4
-rw-r--r--src/librustc/lint/table.rs15
-rw-r--r--src/librustc/ty/context.rs5
-rw-r--r--src/librustc_errors/Cargo.toml1
-rw-r--r--src/librustc_errors/diagnostic.rs4
-rw-r--r--src/librustc_errors/lib.rs7
-rw-r--r--src/librustc_errors/snippet.rs2
-rw-r--r--src/librustc_typeck/check/cast.rs34
-rw-r--r--src/librustc_typeck/check/mod.rs7
-rw-r--r--src/librustc_typeck/check/writeback.rs9
-rw-r--r--src/libsyntax_pos/lib.rs2
13 files changed, 87 insertions, 32 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock
index 93bbf0f227b..f40d50dd59d 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -364,6 +364,7 @@ dependencies = [
 name = "rustc_errors"
 version = "0.0.0"
 dependencies = [
+ "serialize 0.0.0",
  "syntax_pos 0.0.0",
 ]
 
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index edf5666a3a5..362117d860a 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -33,6 +33,7 @@ use lint::{Level, LevelSource, Lint, LintId, LintPass, LintSource};
 use lint::{EarlyLintPassObject, LateLintPassObject};
 use lint::{Default, CommandLine, Node, Allow, Warn, Deny, Forbid};
 use lint::builtin;
+use rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
 use util::nodemap::FxHashMap;
 
 use std::cmp;
@@ -82,7 +83,7 @@ pub struct LintStore {
 
 /// When you call `add_lint` on the session, you wind up storing one
 /// of these, which records a "potential lint" at a particular point.
-#[derive(PartialEq)]
+#[derive(PartialEq, RustcEncodable, RustcDecodable)]
 pub struct EarlyLint {
     /// what lint is this? (e.g., `dead_code`)
     pub id: LintId,
@@ -558,7 +559,7 @@ pub trait LintContext<'tcx>: Sized {
         self.lookup_and_emit(lint, Some(span), msg);
     }
 
-    fn early_lint(&self, early_lint: EarlyLint) {
+    fn early_lint(&self, early_lint: &EarlyLint) {
         let span = early_lint.diagnostic.span.primary_span().expect("early lint w/o primary span");
         let mut err = self.struct_span_lint(early_lint.id.lint,
                                             span,
@@ -774,7 +775,7 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
     // Output any lints that were previously added to the session.
     fn visit_id(&mut self, id: ast::NodeId) {
         let lints = self.sess().lints.borrow_mut().take(id);
-        for early_lint in lints {
+        for early_lint in lints.iter().chain(self.tables.lints.get(id)) {
             debug!("LateContext::visit_id: id={:?} early_lint={:?}", id, early_lint);
             self.early_lint(early_lint);
         }
@@ -1251,7 +1252,7 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
         // Lints may be assigned to the whole crate.
         let lints = cx.sess.lints.borrow_mut().take(ast::CRATE_NODE_ID);
         for early_lint in lints {
-            cx.early_lint(early_lint);
+            cx.early_lint(&early_lint);
         }
 
         // since the root module isn't visited as an item (because it isn't an
@@ -1274,3 +1275,22 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
         }
     }
 }
+
+impl Encodable for LintId {
+    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+        s.emit_str(&self.lint.name.to_lowercase())
+    }
+}
+
+impl Decodable for LintId {
+    #[inline]
+    fn decode<D: Decoder>(d: &mut D) -> Result<LintId, D::Error> {
+        let s = d.read_str()?;
+        ty::tls::with(|tcx| {
+            match tcx.sess.lint_store.borrow().find_lint(&s, tcx.sess, None) {
+                Ok(id) => Ok(id),
+                Err(_) => panic!("invalid lint-id `{}`", s),
+            }
+        })
+    }
+}
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 704e32e2d0c..d12065ca86e 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -31,13 +31,13 @@
 pub use self::Level::*;
 pub use self::LintSource::*;
 
+use hir;
+use hir::intravisit::FnKind;
 use std::hash;
 use std::ascii::AsciiExt;
 use syntax_pos::Span;
-use hir::intravisit::FnKind;
 use syntax::visit as ast_visit;
 use syntax::ast;
-use hir;
 
 pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
                         raw_emit_lint, check_crate, check_ast_crate, gather_attrs,
diff --git a/src/librustc/lint/table.rs b/src/librustc/lint/table.rs
index 3b6d268b08f..f2dab25229a 100644
--- a/src/librustc/lint/table.rs
+++ b/src/librustc/lint/table.rs
@@ -1,9 +1,20 @@
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
 use syntax::ast;
 use syntax_pos::MultiSpan;
 use util::nodemap::NodeMap;
 
 use super::{Lint, LintId, EarlyLint, IntoEarlyLint};
 
+#[derive(RustcEncodable, RustcDecodable)]
 pub struct LintTable {
     map: NodeMap<Vec<EarlyLint>>
 }
@@ -44,6 +55,10 @@ impl LintTable {
         self.map.remove(&id).unwrap_or(vec![])
     }
 
+    pub fn transfer(&mut self, into: &mut LintTable) {
+        into.map.extend(self.map.drain());
+    }
+
     /// Returns the first (id, lint) pair that is non-empty. Used to
     /// implement a sanity check in lints that all node-ids are
     /// visited.
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 5913ed48528..a3b81586738 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -12,6 +12,7 @@
 
 use dep_graph::{DepGraph, DepTrackingMap};
 use session::Session;
+use lint;
 use middle;
 use hir::TraitMap;
 use hir::def::Def;
@@ -237,6 +238,9 @@ pub struct TypeckTables<'tcx> {
     /// Maps a cast expression to its kind. This is keyed on the
     /// *from* expression of the cast, not the cast itself.
     pub cast_kinds: NodeMap<ty::cast::CastKind>,
+
+    /// Lints for the body of this fn generated by typeck.
+    pub lints: lint::LintTable,
 }
 
 impl<'tcx> TypeckTables<'tcx> {
@@ -253,6 +257,7 @@ impl<'tcx> TypeckTables<'tcx> {
             liberated_fn_sigs: NodeMap(),
             fru_field_types: NodeMap(),
             cast_kinds: NodeMap(),
+            lints: lint::LintTable::new(),
         }
     }
 
diff --git a/src/librustc_errors/Cargo.toml b/src/librustc_errors/Cargo.toml
index 2ba1f501a63..78ff52b4b23 100644
--- a/src/librustc_errors/Cargo.toml
+++ b/src/librustc_errors/Cargo.toml
@@ -9,4 +9,5 @@ path = "lib.rs"
 crate-type = ["dylib"]
 
 [dependencies]
+serialize = { path = "../libserialize" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs
index ac39af20189..1b77ead92de 100644
--- a/src/librustc_errors/diagnostic.rs
+++ b/src/librustc_errors/diagnostic.rs
@@ -17,7 +17,7 @@ use syntax_pos::{MultiSpan, Span};
 use snippet::Style;
 
 #[must_use]
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
 pub struct Diagnostic {
     pub level: Level,
     pub message: Vec<(String, Style)>,
@@ -27,7 +27,7 @@ pub struct Diagnostic {
 }
 
 /// For example a note attached to an error.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
 pub struct SubDiagnostic {
     pub level: Level,
     pub message: Vec<(String, Style)>,
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index bf5f7cde7eb..d7bd5ed23c2 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -26,6 +26,7 @@
 
 extern crate term;
 extern crate libc;
+extern crate serialize as rustc_serialize;
 extern crate syntax_pos;
 
 pub use emitter::ColorConfig;
@@ -49,7 +50,7 @@ mod lock;
 use syntax_pos::{BytePos, Loc, FileLinesResult, FileName, MultiSpan, Span, NO_EXPANSION};
 use syntax_pos::MacroBacktrace;
 
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
 pub enum RenderSpan {
     /// A FullSpan renders with both with an initial line for the
     /// message, prefixed by file:linenum, followed by a summary of
@@ -63,7 +64,7 @@ pub enum RenderSpan {
     Suggestion(CodeSuggestion),
 }
 
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
 pub struct CodeSuggestion {
     pub msp: MultiSpan,
     pub substitutes: Vec<String>,
@@ -477,7 +478,7 @@ impl Handler {
 }
 
 
-#[derive(Copy, PartialEq, Clone, Debug)]
+#[derive(Copy, PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)]
 pub enum Level {
     Bug,
     Fatal,
diff --git a/src/librustc_errors/snippet.rs b/src/librustc_errors/snippet.rs
index 95b03677b72..5debbf4d37c 100644
--- a/src/librustc_errors/snippet.rs
+++ b/src/librustc_errors/snippet.rs
@@ -204,7 +204,7 @@ pub struct StyledString {
     pub style: Style,
 }
 
-#[derive(Copy, Clone, Debug, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
 pub enum Style {
     HeaderMsg,
     FileNameStyle,
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 6215b4498dc..441d427fe49 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -311,23 +311,25 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
         let t_cast = self.cast_ty;
         let t_expr = self.expr_ty;
         if t_cast.is_numeric() && t_expr.is_numeric() {
-            fcx.tcx.sess.add_lint(lint::builtin::TRIVIAL_NUMERIC_CASTS,
-                                  self.expr.id,
-                                  self.span,
-                                  format!("trivial numeric cast: `{}` as `{}`. Cast can be \
-                                           replaced by coercion, this might require type \
-                                           ascription or a temporary variable",
-                                          fcx.ty_to_string(t_expr),
-                                          fcx.ty_to_string(t_cast)));
+            fcx.tables.borrow_mut().lints.add_lint(
+                lint::builtin::TRIVIAL_NUMERIC_CASTS,
+                self.expr.id,
+                self.span,
+                format!("trivial numeric cast: `{}` as `{}`. Cast can be \
+                         replaced by coercion, this might require type \
+                         ascription or a temporary variable",
+                        fcx.ty_to_string(t_expr),
+                        fcx.ty_to_string(t_cast)));
         } else {
-            fcx.tcx.sess.add_lint(lint::builtin::TRIVIAL_CASTS,
-                                  self.expr.id,
-                                  self.span,
-                                  format!("trivial cast: `{}` as `{}`. Cast can be \
-                                           replaced by coercion, this might require type \
-                                           ascription or a temporary variable",
-                                          fcx.ty_to_string(t_expr),
-                                          fcx.ty_to_string(t_cast)));
+            fcx.tables.borrow_mut().lints.add_lint(
+                lint::builtin::TRIVIAL_CASTS,
+                self.expr.id,
+                self.span,
+                format!("trivial cast: `{}` as `{}`. Cast can be \
+                         replaced by coercion, this might require type \
+                         ascription or a temporary variable",
+                        fcx.ty_to_string(t_expr),
+                        fcx.ty_to_string(t_cast)));
         }
 
     }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index c435f934125..573cbfcc3b0 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1521,9 +1521,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         if self.diverges.get() == Diverges::Always {
             self.diverges.set(Diverges::WarnedAlways);
 
-            self.tcx.sess.add_lint(lint::builtin::UNREACHABLE_CODE,
-                                   id, span,
-                                   format!("unreachable {}", kind));
+            self.tables.borrow_mut().lints.add_lint(
+                lint::builtin::UNREACHABLE_CODE,
+                id, span,
+                format!("unreachable {}", kind));
         }
     }
 
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 7f82d7829ce..3a467c0296a 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -52,6 +52,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         wbcx.visit_deferred_obligations(item_id);
         wbcx.visit_type_nodes();
         wbcx.visit_cast_types();
+        wbcx.visit_lints();
 
         let tables = self.tcx.alloc_tables(wbcx.tables);
         self.tcx.tables.borrow_mut().insert(item_def_id, tables);
@@ -301,6 +302,14 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
             self.fcx.tables.borrow().cast_kinds.iter().map(|(&key, &value)| (key, value)));
     }
 
+    fn visit_lints(&mut self) {
+        if self.fcx.writeback_errors.get() {
+            return
+        }
+
+        self.fcx.tables.borrow_mut().lints.transfer(&mut self.tables.lints);
+    }
+
     fn visit_anon_types(&self) {
         if self.fcx.writeback_errors.get() {
             return
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 92fdb45caaa..3808923e772 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -66,7 +66,7 @@ pub struct Span {
 ///   the error, and would be rendered with `^^^`.
 /// - they can have a *label*. In this case, the label is written next
 ///   to the mark in the snippet when we render.
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+#[derive(Clone, Debug, Hash, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub struct MultiSpan {
     primary_spans: Vec<Span>,
     span_labels: Vec<(Span, String)>,