1
Fork 0

Add ability for hardwired lints to operate on the diagnostic builder

This commit is contained in:
Manish Goregaokar 2018-02-22 22:34:06 -08:00
parent 3eeabe7b7d
commit bd29696218
4 changed files with 59 additions and 5 deletions

View file

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

View file

@ -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);
}
}
}

View file

@ -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) {

View file

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