From 2a7ae04a6872edd8a1bffa620fde53a2eb2964e1 Mon Sep 17 00:00:00 2001 From: mark Date: Wed, 11 Jul 2018 20:54:12 -0500 Subject: [PATCH] Extend ParseSess to support buffering lints --- src/librustc/lint/builtin.rs | 10 +++++++++ src/librustc/lint/mod.rs | 9 +++++++++ src/librustc_driver/driver.rs | 8 ++++++++ src/libsyntax/early_buffered_lints.rs | 29 +++++++++++++++++++++++++++ src/libsyntax/lib.rs | 2 ++ src/libsyntax/parse/mod.rs | 23 +++++++++++++++++++-- 6 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 src/libsyntax/early_buffered_lints.rs 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>, code_map: Lrc, + pub buffered_lints: Lock>, } 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>(&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)]