]> git.lizzy.rs Git - rust.git/commitdiff
store typeck lints in the `TypeckTables`
authorNiko Matsakis <niko@alum.mit.edu>
Sat, 28 Jan 2017 23:13:21 +0000 (18:13 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Fri, 3 Feb 2017 01:38:16 +0000 (20:38 -0500)
Otherwise they are a "hidden output"

13 files changed:
src/Cargo.lock
src/librustc/lint/context.rs
src/librustc/lint/mod.rs
src/librustc/lint/table.rs
src/librustc/ty/context.rs
src/librustc_errors/Cargo.toml
src/librustc_errors/diagnostic.rs
src/librustc_errors/lib.rs
src/librustc_errors/snippet.rs
src/librustc_typeck/check/cast.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/writeback.rs
src/libsyntax_pos/lib.rs

index 93bbf0f227b1ba691d6500180fbdaa8e72151315..f40d50dd59dc1fdf4183355ed368bc9101200780 100644 (file)
@@ -364,6 +364,7 @@ dependencies = [
 name = "rustc_errors"
 version = "0.0.0"
 dependencies = [
+ "serialize 0.0.0",
  "syntax_pos 0.0.0",
 ]
 
index edf5666a3a5f7f438862967ef6d7244218fb83b0..362117d860a5c15f3aece6d8d2c1a9f497a4f634 100644 (file)
@@ -33,6 +33,7 @@
 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 @@ fn span_lint<S: Into<MultiSpan>>(&self, lint: &'static Lint, span: S, msg: &str)
         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 @@ fn nested_visit_map<'this>(&'this mut self) -> hir_visit::NestedVisitorMap<'this
     // 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),
+            }
+        })
+    }
+}
index 704e32e2d0c1a782ea9ec406b0ea8b4642db4e7a..d12065ca86e144c5d0e682e33b596ed4122d5275 100644 (file)
 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,
index 3b6d268b08fb08219717d44420cc6b3d50b7fda7..f2dab25229ae4e0ec3ed063c38dbd8b70d328637 100644 (file)
@@ -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 @@ pub fn take(&mut self, id: ast::NodeId) -> Vec<EarlyLint> {
         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.
index 5913ed48528f7b1a270548c0cabbdbda597f8fe4..a3b81586738b5dadee1bad445f9eee38dc99eae0 100644 (file)
@@ -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 @@ pub fn empty() -> TypeckTables<'tcx> {
             liberated_fn_sigs: NodeMap(),
             fru_field_types: NodeMap(),
             cast_kinds: NodeMap(),
+            lints: lint::LintTable::new(),
         }
     }
 
index 2ba1f501a63d800a9b659b33353480e515568bf4..78ff52b4b2371491c5cbf566293a52c588957e01 100644 (file)
@@ -9,4 +9,5 @@ path = "lib.rs"
 crate-type = ["dylib"]
 
 [dependencies]
+serialize = { path = "../libserialize" }
 syntax_pos = { path = "../libsyntax_pos" }
index ac39af2018998dfeeda3a9fe457242daaccb5557..1b77ead92deb6a4084d6539c7658fa8678af9cbd 100644 (file)
@@ -17,7 +17,7 @@
 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)>,
index bf5f7cde7eb06b9ac56eaa1119838ecc5f6afbd2..d7bd5ed23c2b0af883ce9687447d15d233f63755 100644 (file)
@@ -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 @@
 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 @@ pub fn emit_with_code(&self, msp: &MultiSpan, msg: &str, code: &str, lvl: Level)
 }
 
 
-#[derive(Copy, PartialEq, Clone, Debug)]
+#[derive(Copy, PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)]
 pub enum Level {
     Bug,
     Fatal,
index 95b03677b72857b9ee6df5ddbe7a0736a83d1333..5debbf4d37c20286fab1be9ed9b763888c84327f 100644 (file)
@@ -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,
index 6215b4498dc684ee3a63454b1c8bf1d242abfc9f..441d427fe499e366303512c107e6733b31e9f414 100644 (file)
@@ -311,23 +311,25 @@ fn trivial_cast_lint(&self, fcx: &FnCtxt<'a, 'gcx, '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)));
         }
 
     }
index c435f9341253e92920ff621ecc13e8fa26486eb2..573cbfcc3b062bbfdd8a8e17945c46e43100662c 100644 (file)
@@ -1521,9 +1521,10 @@ fn warn_if_unreachable(&self, id: ast::NodeId, span: Span, kind: &str) {
         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));
         }
     }
 
index 7f82d7829ce52d7e700ff06bce99f8552f6bb2c2..3a467c0296a528d7d35c444e6a5664d0e06763c5 100644 (file)
@@ -52,6 +52,7 @@ pub fn resolve_type_vars_in_body(&self, body: &'gcx hir::Body) {
         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 @@ fn visit_cast_types(&mut self) {
             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
index 92fdb45caaaeffbc4425c7370dc7cfff1cc69a74..3808923e7728f9813d4cb33a5e1d6dd0341dc602 100644 (file)
@@ -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)>,