Skip to content

Commit

Permalink
Extend ParseSess to support buffering lints
Browse files Browse the repository at this point in the history
  • Loading branch information
mark-i-m committed Jul 24, 2018
1 parent 6a1c063 commit 2a7ae04
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 2 deletions.
10 changes: 10 additions & 0 deletions src/librustc/lint/builtin.rs
Expand Up @@ -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)]
Expand Down Expand Up @@ -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,
)
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/librustc/lint/mod.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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()
Expand Down
8 changes: 8 additions & 0 deletions src/librustc_driver/driver.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -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)
}

Expand Down
29 changes: 29 additions & 0 deletions 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,
}
2 changes: 2 additions & 0 deletions src/libsyntax/lib.rs
Expand Up @@ -181,6 +181,8 @@ pub mod ext {
}
}

pub mod early_buffered_lints;

#[cfg(test)]
mod test_snippet;

Expand Down
23 changes: 21 additions & 2 deletions src/libsyntax/parse/mod.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand All @@ -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)]
Expand Down

0 comments on commit 2a7ae04

Please sign in to comment.