// Output any lints that were previously added to the session.
fn visit_id(&mut self, id: ast::NodeId) {
- if let Some(lints) = self.sess().lints.borrow_mut().remove(&id) {
- debug!("LateContext::visit_id: id={:?} lints={:?}", id, lints);
- for early_lint in lints {
- self.early_lint(early_lint);
- }
+ let lints = self.sess().lints.borrow_mut().take(id);
+ for early_lint in lints {
+ debug!("LateContext::visit_id: id={:?} early_lint={:?}", id, early_lint);
+ self.early_lint(early_lint);
}
}
// 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() {
+ if let Some((id, v)) = tcx.sess.lints.borrow().get_any() {
for early_lint in v {
span_bug!(early_lint.diagnostic.span.clone(),
"unprocessed lint {:?} at {}",
// Visit the whole 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 early_lint in lints {
- cx.early_lint(early_lint);
- }
+ let lints = cx.sess.lints.borrow_mut().take(ast::CRATE_NODE_ID);
+ for early_lint in lints {
+ cx.early_lint(early_lint);
}
// since the root module isn't visited as an item (because it isn't an
// 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 (_, v) in sess.lints.borrow().get_any() {
for early_lint in v {
span_bug!(early_lint.diagnostic.span.clone(), "unprocessed lint {:?}", early_lint);
}
raw_emit_lint, check_crate, check_ast_crate, gather_attrs,
raw_struct_lint, FutureIncompatibleInfo, EarlyLint, IntoEarlyLint};
+pub use lint::table::LintTable;
+
/// Specification of a single lint.
#[derive(Copy, Clone, Debug)]
pub struct Lint {
pub mod builtin;
mod context;
+mod table;
--- /dev/null
+use syntax::ast;
+use syntax_pos::MultiSpan;
+use util::nodemap::NodeMap;
+
+use super::{Lint, LintId, EarlyLint, IntoEarlyLint};
+
+pub struct LintTable {
+ map: NodeMap<Vec<EarlyLint>>
+}
+
+impl LintTable {
+ pub fn new() -> Self {
+ LintTable { map: NodeMap() }
+ }
+
+ pub fn add_lint<S: Into<MultiSpan>>(&mut self,
+ lint: &'static Lint,
+ id: ast::NodeId,
+ sp: S,
+ msg: String)
+ {
+ self.add_lint_diagnostic(lint, id, (sp, &msg[..]))
+ }
+
+ pub fn add_lint_diagnostic<M>(&mut self,
+ lint: &'static Lint,
+ id: ast::NodeId,
+ msg: M)
+ where M: IntoEarlyLint,
+ {
+ let lint_id = LintId::of(lint);
+ let early_lint = msg.into_early_lint(lint_id);
+ let arr = self.map.entry(id).or_insert(vec![]);
+ if !arr.contains(&early_lint) {
+ arr.push(early_lint);
+ }
+ }
+
+ pub fn get(&self, id: ast::NodeId) -> &[EarlyLint] {
+ self.map.get(&id).map(|v| &v[..]).unwrap_or(&[])
+ }
+
+ pub fn take(&mut self, id: ast::NodeId) -> Vec<EarlyLint> {
+ self.map.remove(&id).unwrap_or(vec![])
+ }
+
+ /// Returns the first (id, lint) pair that is non-empty. Used to
+ /// implement a sanity check in lints that all node-ids are
+ /// visited.
+ pub fn get_any(&self) -> Option<(&ast::NodeId, &Vec<EarlyLint>)> {
+ self.map.iter()
+ .filter(|&(_, v)| !v.is_empty())
+ .next()
+ }
+}
+
use session::search_paths::PathKind;
use session::config::DebugInfoLevel;
use ty::tls;
-use util::nodemap::{NodeMap, FxHashMap, FxHashSet};
+use util::nodemap::{FxHashMap, FxHashSet};
use util::common::duration_to_secs_str;
use mir::transform as mir_pass;
pub local_crate_source_file: Option<PathBuf>,
pub working_dir: PathBuf,
pub lint_store: RefCell<lint::LintStore>,
- pub lints: RefCell<NodeMap<Vec<lint::EarlyLint>>>,
+ pub lints: RefCell<lint::LintTable>,
/// Set of (LintId, span, message) tuples tracking lint (sub)diagnostics
/// that have been set once, but should not be set again, in order to avoid
/// redundantly verbose output (Issue #24690).
pub fn unimpl(&self, msg: &str) -> ! {
self.diagnostic().unimpl(msg)
}
+
pub fn add_lint<S: Into<MultiSpan>>(&self,
lint: &'static lint::Lint,
id: ast::NodeId,
sp: S,
msg: String)
{
- self.add_lint_diagnostic(lint, id, (sp, &msg[..]))
+ self.lints.borrow_mut().add_lint(lint, id, sp, msg);
}
pub fn add_lint_diagnostic<M>(&self,
msg: M)
where M: lint::IntoEarlyLint,
{
- let lint_id = lint::LintId::of(lint);
- let mut lints = self.lints.borrow_mut();
- let early_lint = msg.into_early_lint(lint_id);
- if let Some(arr) = lints.get_mut(&id) {
- if !arr.contains(&early_lint) {
- arr.push(early_lint);
- }
- return;
- }
- lints.insert(id, vec![early_lint]);
+ self.lints.borrow_mut().add_lint_diagnostic(lint, id, msg);
}
+
pub fn reserve_node_ids(&self, count: usize) -> ast::NodeId {
let id = self.next_node_id.get();
local_crate_source_file: local_crate_source_file,
working_dir: env::current_dir().unwrap(),
lint_store: RefCell::new(lint::LintStore::new()),
- lints: RefCell::new(NodeMap()),
+ lints: RefCell::new(lint::LintTable::new()),
one_time_diagnostics: RefCell::new(FxHashSet()),
plugin_llvm_passes: RefCell::new(Vec::new()),
mir_passes: RefCell::new(mir_pass::Passes::new()),