Skip to content

Commit 2a7ae04

Browse files
committed
Extend ParseSess to support buffering lints
1 parent 6a1c063 commit 2a7ae04

File tree

6 files changed

+79
-2
lines changed

6 files changed

+79
-2
lines changed

src/librustc/lint/builtin.rs

+10
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,15 @@ declare_lint! {
331331
via the module system"
332332
}
333333

334+
/// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`.
335+
pub mod parser {
336+
declare_lint! {
337+
pub QUESTION_MARK_MACRO_SEP,
338+
Warn,
339+
"detects the use of `?` as a macro separator"
340+
}
341+
}
342+
334343
/// Does nothing as a lint pass, but registers some `Lint`s
335344
/// which are used by other parts of the compiler.
336345
#[derive(Copy, Clone)]
@@ -389,6 +398,7 @@ impl LintPass for HardwiredLints {
389398
WHERE_CLAUSES_OBJECT_SAFETY,
390399
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
391400
MACRO_USE_EXTERN_CRATE,
401+
parser::QUESTION_MARK_MACRO_SEP,
392402
)
393403
}
394404
}

src/librustc/lint/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@ use hir::def_id::{CrateNum, LOCAL_CRATE};
3838
use hir::intravisit;
3939
use hir;
4040
use lint::builtin::BuiltinLintDiagnostics;
41+
use lint::builtin::parser::QUESTION_MARK_MACRO_SEP;
4142
use session::{Session, DiagnosticMessageId};
4243
use std::{hash, ptr};
4344
use syntax::ast;
4445
use syntax::codemap::{MultiSpan, ExpnFormat};
46+
use syntax::early_buffered_lints::BufferedEarlyLintId;
4547
use syntax::edition::Edition;
4648
use syntax::symbol::Symbol;
4749
use syntax::visit as ast_visit;
@@ -86,6 +88,13 @@ pub struct Lint {
8688
}
8789

8890
impl Lint {
91+
/// Returns the `rust::lint::Lint` for a `syntax::early_buffered_lints::BufferedEarlyLintId`.
92+
pub fn from_parser_lint_id(lint_id: BufferedEarlyLintId) -> &'static Self {
93+
match lint_id {
94+
BufferedEarlyLintId::QuestionMarkMacroSep => QUESTION_MARK_MACRO_SEP,
95+
}
96+
}
97+
8998
/// Get the lint's name, with ASCII letters converted to lowercase.
9099
pub fn name_lower(&self) -> String {
91100
self.name.to_ascii_lowercase()

src/librustc_driver/driver.rs

+8
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ use std::path::{Path, PathBuf};
5252
use rustc_data_structures::sync::{self, Lrc, Lock};
5353
use std::sync::mpsc;
5454
use syntax::{self, ast, attr, diagnostics, visit};
55+
use syntax::early_buffered_lints::BufferedEarlyLint;
5556
use syntax::ext::base::ExtCtxt;
5657
use syntax::fold::Folder;
5758
use syntax::parse::{self, PResult};
@@ -696,6 +697,13 @@ pub fn phase_1_parse_input<'a>(
696697
hir_stats::print_ast_stats(&krate, "PRE EXPANSION AST STATS");
697698
}
698699

700+
// Add all buffered lints from the `ParseSess` to the `Session`.
701+
let mut parse_sess_buffered = sess.parse_sess.buffered_lints.borrow_mut();
702+
for BufferedEarlyLint{id, span, msg, lint_id} in parse_sess_buffered.drain(..) {
703+
let lint = lint::Lint::from_parser_lint_id(lint_id);
704+
sess.buffer_lint(lint, id, span, &msg);
705+
}
706+
699707
Ok(krate)
700708
}
701709

src/libsyntax/early_buffered_lints.rs

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//! Allows the buffering of lints for later.
2+
//!
3+
//! Since we cannot have a dependency on `librustc`, we implement some types here that are somewhat
4+
//! redundant. Later, these types can be converted to types for use by the rest of the compiler.
5+
6+
use syntax::ast::NodeId;
7+
use syntax_pos::MultiSpan;
8+
9+
/// Since we cannot import `LintId`s from `rustc::lint`, we define some Ids here which can later be
10+
/// passed to `rustc::lint::Lint::from_parser_lint_id` to get a `rustc::lint::Lint`.
11+
pub enum BufferedEarlyLintId {
12+
/// Usage of `?` as a macro separator is deprecated.
13+
QuestionMarkMacroSep,
14+
}
15+
16+
/// Stores buffered lint info which can later be passed to `librustc`.
17+
pub struct BufferedEarlyLint {
18+
/// The span of code that we are linting on.
19+
pub span: MultiSpan,
20+
21+
/// The lint message.
22+
pub msg: String,
23+
24+
/// The `NodeId` of the AST node that generated the lint.
25+
pub id: NodeId,
26+
27+
/// A lint Id that can be passed to `rustc::lint::Lint::from_parser_lint_id`.
28+
pub lint_id: BufferedEarlyLintId,
29+
}

src/libsyntax/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ pub mod ext {
181181
}
182182
}
183183

184+
pub mod early_buffered_lints;
185+
184186
#[cfg(test)]
185187
mod test_snippet;
186188

src/libsyntax/parse/mod.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@
1111
//! The main parser interface
1212
1313
use rustc_data_structures::sync::{Lrc, Lock};
14-
use ast::{self, CrateConfig};
14+
use ast::{self, CrateConfig, NodeId};
15+
use early_buffered_lints::{BufferedEarlyLint, BufferedEarlyLintId};
1516
use codemap::{CodeMap, FilePathMapping};
16-
use syntax_pos::{Span, FileMap, FileName};
17+
use syntax_pos::{Span, FileMap, FileName, MultiSpan};
1718
use errors::{Handler, ColorConfig, DiagnosticBuilder};
1819
use feature_gate::UnstableFeatures;
1920
use parse::parser::Parser;
@@ -57,6 +58,7 @@ pub struct ParseSess {
5758
/// Used to determine and report recursive mod inclusions
5859
included_mod_stack: Lock<Vec<PathBuf>>,
5960
code_map: Lrc<CodeMap>,
61+
pub buffered_lints: Lock<Vec<BufferedEarlyLint>>,
6062
}
6163

6264
impl ParseSess {
@@ -80,12 +82,29 @@ impl ParseSess {
8082
included_mod_stack: Lock::new(vec![]),
8183
code_map,
8284
non_modrs_mods: Lock::new(vec![]),
85+
buffered_lints: Lock::new(vec![]),
8386
}
8487
}
8588

8689
pub fn codemap(&self) -> &CodeMap {
8790
&self.code_map
8891
}
92+
93+
pub fn buffer_lint<S: Into<MultiSpan>>(&self,
94+
lint_id: BufferedEarlyLintId,
95+
span: S,
96+
id: NodeId,
97+
msg: &str,
98+
) {
99+
self.buffered_lints
100+
.borrow_mut()
101+
.push(BufferedEarlyLint{
102+
span: span.into(),
103+
id,
104+
msg: msg.into(),
105+
lint_id,
106+
});
107+
}
89108
}
90109

91110
#[derive(Clone)]

0 commit comments

Comments
 (0)