Extend ParseSess to support buffering lints

This commit is contained in:
mark 2018-07-11 20:54:12 -05:00
parent 6a1c0637ce
commit 2a7ae04a68
6 changed files with 79 additions and 2 deletions

View File

@ -331,6 +331,15 @@
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 @@ fn get_lints(&self) -> LintArray {
WHERE_CLAUSES_OBJECT_SAFETY,
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
MACRO_USE_EXTERN_CRATE,
parser::QUESTION_MARK_MACRO_SEP,
)
}
}

View File

@ -38,10 +38,12 @@
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()

View File

@ -52,6 +52,7 @@
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)
}

View File

@ -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,
}

View File

@ -181,6 +181,8 @@ pub mod tt {
}
}
pub mod early_buffered_lints;
#[cfg(test)]
mod test_snippet;

View File

@ -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 @@ pub fn with_span_handler(handler: Handler, code_map: Lrc<CodeMap>) -> 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)]