Add ability for hardwired lints to operate on the diagnostic builder
This commit is contained in:
parent
3eeabe7b7d
commit
bd29696218
4 changed files with 59 additions and 5 deletions
|
@ -14,8 +14,11 @@
|
|||
//! compiler code, rather than using their own custom pass. Those
|
||||
//! lints are all available in `rustc_lint::builtin`.
|
||||
|
||||
use errors::DiagnosticBuilder;
|
||||
use lint::{LintPass, LateLintPass, LintArray};
|
||||
use session::Session;
|
||||
use session::config::Epoch;
|
||||
use syntax::codemap::Span;
|
||||
|
||||
declare_lint! {
|
||||
pub CONST_ERR,
|
||||
|
@ -312,4 +315,27 @@ impl LintPass for HardwiredLints {
|
|||
}
|
||||
}
|
||||
|
||||
// this could be a closure, but then implementing derive traits
|
||||
// becomes hacky (and it gets allocated)
|
||||
#[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub enum BuiltinLintDiagnostics {
|
||||
Normal,
|
||||
BareTraitObject(Span)
|
||||
}
|
||||
|
||||
impl BuiltinLintDiagnostics {
|
||||
pub fn run(self, sess: &Session, db: &mut DiagnosticBuilder) {
|
||||
match self {
|
||||
BuiltinLintDiagnostics::Normal => (),
|
||||
BuiltinLintDiagnostics::BareTraitObject(span) => {
|
||||
let sugg = match sess.codemap().span_to_snippet(span) {
|
||||
Ok(s) => format!("dyn {}", s),
|
||||
Err(_) => format!("dyn <type>")
|
||||
};
|
||||
db.span_suggestion(span, "use `dyn`", sugg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {}
|
||||
|
|
|
@ -29,6 +29,7 @@ use self::TargetLint::*;
|
|||
use std::slice;
|
||||
use lint::{EarlyLintPassObject, LateLintPassObject};
|
||||
use lint::{Level, Lint, LintId, LintPass, LintBuffer};
|
||||
use lint::builtin::BuiltinLintDiagnostics;
|
||||
use lint::levels::{LintLevelSets, LintLevelsBuilder};
|
||||
use middle::privacy::AccessLevels;
|
||||
use rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
|
||||
|
@ -92,6 +93,7 @@ pub struct BufferedEarlyLint {
|
|||
pub ast_id: ast::NodeId,
|
||||
pub span: MultiSpan,
|
||||
pub msg: String,
|
||||
pub diagnostic: BuiltinLintDiagnostics,
|
||||
}
|
||||
|
||||
/// Extra information for a future incompatibility lint. See the call
|
||||
|
@ -446,6 +448,16 @@ pub trait LintContext<'tcx>: Sized {
|
|||
self.lookup(lint, span, msg).emit();
|
||||
}
|
||||
|
||||
fn lookup_and_emit_with_diagnostics<S: Into<MultiSpan>>(&self,
|
||||
lint: &'static Lint,
|
||||
span: Option<S>,
|
||||
msg: &str,
|
||||
diagnostic: BuiltinLintDiagnostics) {
|
||||
let mut db = self.lookup(lint, span, msg);
|
||||
diagnostic.run(self.sess(), &mut db);
|
||||
db.emit();
|
||||
}
|
||||
|
||||
fn lookup<S: Into<MultiSpan>>(&self,
|
||||
lint: &'static Lint,
|
||||
span: Option<S>,
|
||||
|
@ -516,9 +528,10 @@ impl<'a> EarlyContext<'a> {
|
|||
|
||||
fn check_id(&mut self, id: ast::NodeId) {
|
||||
for early_lint in self.buffered.take(id) {
|
||||
self.lookup_and_emit(early_lint.lint_id.lint,
|
||||
Some(early_lint.span.clone()),
|
||||
&early_lint.msg);
|
||||
self.lookup_and_emit_with_diagnostics(early_lint.lint_id.lint,
|
||||
Some(early_lint.span.clone()),
|
||||
&early_lint.msg,
|
||||
early_lint.diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ use errors::{DiagnosticBuilder, DiagnosticId};
|
|||
use hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||
use hir::intravisit::{self, FnKind};
|
||||
use hir;
|
||||
use lint::builtin::BuiltinLintDiagnostics;
|
||||
use session::{config, Session, DiagnosticMessageId};
|
||||
use std::hash;
|
||||
use syntax::ast;
|
||||
|
@ -399,12 +400,14 @@ impl LintBuffer {
|
|||
lint: &'static Lint,
|
||||
id: ast::NodeId,
|
||||
sp: MultiSpan,
|
||||
msg: &str) {
|
||||
msg: &str,
|
||||
diagnostic: BuiltinLintDiagnostics) {
|
||||
let early_lint = BufferedEarlyLint {
|
||||
lint_id: LintId::of(lint),
|
||||
ast_id: id,
|
||||
span: sp,
|
||||
msg: msg.to_string(),
|
||||
diagnostic
|
||||
};
|
||||
let arr = self.map.entry(id).or_insert(Vec::new());
|
||||
if !arr.contains(&early_lint) {
|
||||
|
|
|
@ -16,6 +16,7 @@ use ich::Fingerprint;
|
|||
|
||||
use ich;
|
||||
use lint;
|
||||
use lint::builtin::BuiltinLintDiagnostics;
|
||||
use middle::allocator::AllocatorKind;
|
||||
use middle::dependency_format;
|
||||
use session::search_paths::PathKind;
|
||||
|
@ -341,7 +342,18 @@ impl Session {
|
|||
sp: S,
|
||||
msg: &str) {
|
||||
match *self.buffered_lints.borrow_mut() {
|
||||
Some(ref mut buffer) => buffer.add_lint(lint, id, sp.into(), msg),
|
||||
Some(ref mut buffer) => buffer.add_lint(lint, id, sp.into(),
|
||||
msg, BuiltinLintDiagnostics::Normal),
|
||||
None => bug!("can't buffer lints after HIR lowering"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn buffer_lint_with_diagnostic<S: Into<MultiSpan>>(&self,
|
||||
lint: &'static lint::Lint, id: ast::NodeId, sp: S,
|
||||
msg: &str, diagnostic: BuiltinLintDiagnostics) {
|
||||
match *self.buffered_lints.borrow_mut() {
|
||||
Some(ref mut buffer) => buffer.add_lint(lint, id, sp.into(),
|
||||
msg, diagnostic),
|
||||
None => bug!("can't buffer lints after HIR lowering"),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue