store typeck lints in the TypeckTables
Otherwise they are a "hidden output"
This commit is contained in:
parent
65b93ebcb8
commit
d9aaca71cc
1
src/Cargo.lock
generated
1
src/Cargo.lock
generated
@ -364,6 +364,7 @@ dependencies = [
|
||||
name = "rustc_errors"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"serialize 0.0.0",
|
||||
"syntax_pos 0.0.0",
|
||||
]
|
||||
|
||||
|
@ -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),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,4 +9,5 @@ path = "lib.rs"
|
||||
crate-type = ["dylib"]
|
||||
|
||||
[dependencies]
|
||||
serialize = { path = "../libserialize" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
@ -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)>,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -311,7 +311,8 @@ 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,
|
||||
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 \
|
||||
@ -320,7 +321,8 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
|
||||
fcx.ty_to_string(t_expr),
|
||||
fcx.ty_to_string(t_cast)));
|
||||
} else {
|
||||
fcx.tcx.sess.add_lint(lint::builtin::TRIVIAL_CASTS,
|
||||
fcx.tables.borrow_mut().lints.add_lint(
|
||||
lint::builtin::TRIVIAL_CASTS,
|
||||
self.expr.id,
|
||||
self.span,
|
||||
format!("trivial cast: `{}` as `{}`. Cast can be \
|
||||
|
@ -1521,7 +1521,8 @@ 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,
|
||||
self.tables.borrow_mut().lints.add_lint(
|
||||
lint::builtin::UNREACHABLE_CODE,
|
||||
id, span,
|
||||
format!("unreachable {}", kind));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)>,
|
||||
|
Loading…
Reference in New Issue
Block a user