summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormark <markm@cs.wisc.edu>2018-07-11 20:54:12 -0500
committermark <markm@cs.wisc.edu>2018-07-23 21:54:43 -0500
commit2a7ae04a6872edd8a1bffa620fde53a2eb2964e1 (patch)
tree1bac89ee27dfd99f1f5e88fed3182d8d0884e657
parent6a1c0637ce44aeea6c60527f4c0e7fb33f2bcd0d (diff)
downloadrust-2a7ae04a6872edd8a1bffa620fde53a2eb2964e1.tar.gz
Extend ParseSess to support buffering lints
-rw-r--r--src/librustc/lint/builtin.rs10
-rw-r--r--src/librustc/lint/mod.rs9
-rw-r--r--src/librustc_driver/driver.rs8
-rw-r--r--src/libsyntax/early_buffered_lints.rs29
-rw-r--r--src/libsyntax/lib.rs2
-rw-r--r--src/libsyntax/parse/mod.rs23
6 files changed, 79 insertions, 2 deletions
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 47c5f464131..495b4d32e06 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -331,6 +331,15 @@ declare_lint! {
via the module system"
}
+/// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`.
+pub mod parser {
+ declare_lint! {
+ pub QUESTION_MARK_MACRO_SEP,
+ Warn,
+ "detects the use of `?` as a macro separator"
+ }
+}
+
/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
@@ -389,6 +398,7 @@ impl LintPass for HardwiredLints {
WHERE_CLAUSES_OBJECT_SAFETY,
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
MACRO_USE_EXTERN_CRATE,
+ parser::QUESTION_MARK_MACRO_SEP,
)
}
}
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index c0f3c351d26..a5c82aa6303 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -38,10 +38,12 @@ use hir::def_id::{CrateNum, LOCAL_CRATE};
use hir::intravisit;
use hir;
use lint::builtin::BuiltinLintDiagnostics;
+use lint::builtin::parser::QUESTION_MARK_MACRO_SEP;
use session::{Session, DiagnosticMessageId};
use std::{hash, ptr};
use syntax::ast;
use syntax::codemap::{MultiSpan, ExpnFormat};
+use syntax::early_buffered_lints::BufferedEarlyLintId;
use syntax::edition::Edition;
use syntax::symbol::Symbol;
use syntax::visit as ast_visit;
@@ -86,6 +88,13 @@ pub struct Lint {
}
impl Lint {
+ /// Returns the `rust::lint::Lint` for a `syntax::early_buffered_lints::BufferedEarlyLintId`.
+ pub fn from_parser_lint_id(lint_id: BufferedEarlyLintId) -> &'static Self {
+ match lint_id {
+ BufferedEarlyLintId::QuestionMarkMacroSep => QUESTION_MARK_MACRO_SEP,
+ }
+ }
+
/// Get the lint's name, with ASCII letters converted to lowercase.
pub fn name_lower(&self) -> String {
self.name.to_ascii_lowercase()
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index c016a131507..3e14ec6f8d4 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -52,6 +52,7 @@ use std::path::{Path, PathBuf};
use rustc_data_structures::sync::{self, Lrc, Lock};
use std::sync::mpsc;
use syntax::{self, ast, attr, diagnostics, visit};
+use syntax::early_buffered_lints::BufferedEarlyLint;
use syntax::ext::base::ExtCtxt;
use syntax::fold::Folder;
use syntax::parse::{self, PResult};
@@ -696,6 +697,13 @@ pub fn phase_1_parse_input<'a>(
hir_stats::print_ast_stats(&krate, "PRE EXPANSION AST STATS");
}
+ // Add all buffered lints from the `ParseSess` to the `Session`.
+ let mut parse_sess_buffered = sess.parse_sess.buffered_lints.borrow_mut();
+ for BufferedEarlyLint{id, span, msg, lint_id} in parse_sess_buffered.drain(..) {
+ let lint = lint::Lint::from_parser_lint_id(lint_id);
+ sess.buffer_lint(lint, id, span, &msg);
+ }
+
Ok(krate)
}
diff --git a/src/libsyntax/early_buffered_lints.rs b/src/libsyntax/early_buffered_lints.rs
new file mode 100644
index 00000000000..204e07625ad
--- /dev/null
+++ b/src/libsyntax/early_buffered_lints.rs
@@ -0,0 +1,29 @@
+//! Allows the buffering of lints for later.
+//!
+//! Since we cannot have a dependency on `librustc`, we implement some types here that are somewhat
+//! redundant. Later, these types can be converted to types for use by the rest of the compiler.
+
+use syntax::ast::NodeId;
+use syntax_pos::MultiSpan;
+
+/// Since we cannot import `LintId`s from `rustc::lint`, we define some Ids here which can later be
+/// passed to `rustc::lint::Lint::from_parser_lint_id` to get a `rustc::lint::Lint`.
+pub enum BufferedEarlyLintId {
+ /// Usage of `?` as a macro separator is deprecated.
+ QuestionMarkMacroSep,
+}
+
+/// Stores buffered lint info which can later be passed to `librustc`.
+pub struct BufferedEarlyLint {
+ /// The span of code that we are linting on.
+ pub span: MultiSpan,
+
+ /// The lint message.
+ pub msg: String,
+
+ /// The `NodeId` of the AST node that generated the lint.
+ pub id: NodeId,
+
+ /// A lint Id that can be passed to `rustc::lint::Lint::from_parser_lint_id`.
+ pub lint_id: BufferedEarlyLintId,
+}
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index ffaad9bf94c..d241ae1d442 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -181,6 +181,8 @@ pub mod ext {
}
}
+pub mod early_buffered_lints;
+
#[cfg(test)]
mod test_snippet;
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 1754e5f1b9a..5dbf569766e 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -11,9 +11,10 @@
//! The main parser interface
use rustc_data_structures::sync::{Lrc, Lock};
-use ast::{self, CrateConfig};
+use ast::{self, CrateConfig, NodeId};
+use early_buffered_lints::{BufferedEarlyLint, BufferedEarlyLintId};
use codemap::{CodeMap, FilePathMapping};
-use syntax_pos::{Span, FileMap, FileName};
+use syntax_pos::{Span, FileMap, FileName, MultiSpan};
use errors::{Handler, ColorConfig, DiagnosticBuilder};
use feature_gate::UnstableFeatures;
use parse::parser::Parser;
@@ -57,6 +58,7 @@ pub struct ParseSess {
/// Used to determine and report recursive mod inclusions
included_mod_stack: Lock<Vec<PathBuf>>,
code_map: Lrc<CodeMap>,
+ pub buffered_lints: Lock<Vec<BufferedEarlyLint>>,
}
impl ParseSess {
@@ -80,12 +82,29 @@ impl ParseSess {
included_mod_stack: Lock::new(vec![]),
code_map,
non_modrs_mods: Lock::new(vec![]),
+ buffered_lints: Lock::new(vec![]),
}
}
pub fn codemap(&self) -> &CodeMap {
&self.code_map
}
+
+ pub fn buffer_lint<S: Into<MultiSpan>>(&self,
+ lint_id: BufferedEarlyLintId,
+ span: S,
+ id: NodeId,
+ msg: &str,
+ ) {
+ self.buffered_lints
+ .borrow_mut()
+ .push(BufferedEarlyLint{
+ span: span.into(),
+ id,
+ msg: msg.into(),
+ lint_id,
+ });
+ }
}
#[derive(Clone)]