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
|
//! compiler code, rather than using their own custom pass. Those
|
||||||
//! lints are all available in `rustc_lint::builtin`.
|
//! lints are all available in `rustc_lint::builtin`.
|
||||||
|
|
||||||
|
use errors::DiagnosticBuilder;
|
||||||
use lint::{LintPass, LateLintPass, LintArray};
|
use lint::{LintPass, LateLintPass, LintArray};
|
||||||
|
use session::Session;
|
||||||
use session::config::Epoch;
|
use session::config::Epoch;
|
||||||
|
use syntax::codemap::Span;
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub CONST_ERR,
|
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 {}
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {}
|
||||||
|
|
|
@ -29,6 +29,7 @@ use self::TargetLint::*;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use lint::{EarlyLintPassObject, LateLintPassObject};
|
use lint::{EarlyLintPassObject, LateLintPassObject};
|
||||||
use lint::{Level, Lint, LintId, LintPass, LintBuffer};
|
use lint::{Level, Lint, LintId, LintPass, LintBuffer};
|
||||||
|
use lint::builtin::BuiltinLintDiagnostics;
|
||||||
use lint::levels::{LintLevelSets, LintLevelsBuilder};
|
use lint::levels::{LintLevelSets, LintLevelsBuilder};
|
||||||
use middle::privacy::AccessLevels;
|
use middle::privacy::AccessLevels;
|
||||||
use rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
|
use rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
|
||||||
|
@ -92,6 +93,7 @@ pub struct BufferedEarlyLint {
|
||||||
pub ast_id: ast::NodeId,
|
pub ast_id: ast::NodeId,
|
||||||
pub span: MultiSpan,
|
pub span: MultiSpan,
|
||||||
pub msg: String,
|
pub msg: String,
|
||||||
|
pub diagnostic: BuiltinLintDiagnostics,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extra information for a future incompatibility lint. See the call
|
/// 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();
|
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,
|
fn lookup<S: Into<MultiSpan>>(&self,
|
||||||
lint: &'static Lint,
|
lint: &'static Lint,
|
||||||
span: Option<S>,
|
span: Option<S>,
|
||||||
|
@ -516,9 +528,10 @@ impl<'a> EarlyContext<'a> {
|
||||||
|
|
||||||
fn check_id(&mut self, id: ast::NodeId) {
|
fn check_id(&mut self, id: ast::NodeId) {
|
||||||
for early_lint in self.buffered.take(id) {
|
for early_lint in self.buffered.take(id) {
|
||||||
self.lookup_and_emit(early_lint.lint_id.lint,
|
self.lookup_and_emit_with_diagnostics(early_lint.lint_id.lint,
|
||||||
Some(early_lint.span.clone()),
|
Some(early_lint.span.clone()),
|
||||||
&early_lint.msg);
|
&early_lint.msg,
|
||||||
|
early_lint.diagnostic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ use errors::{DiagnosticBuilder, DiagnosticId};
|
||||||
use hir::def_id::{CrateNum, LOCAL_CRATE};
|
use hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||||
use hir::intravisit::{self, FnKind};
|
use hir::intravisit::{self, FnKind};
|
||||||
use hir;
|
use hir;
|
||||||
|
use lint::builtin::BuiltinLintDiagnostics;
|
||||||
use session::{config, Session, DiagnosticMessageId};
|
use session::{config, Session, DiagnosticMessageId};
|
||||||
use std::hash;
|
use std::hash;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
@ -399,12 +400,14 @@ impl LintBuffer {
|
||||||
lint: &'static Lint,
|
lint: &'static Lint,
|
||||||
id: ast::NodeId,
|
id: ast::NodeId,
|
||||||
sp: MultiSpan,
|
sp: MultiSpan,
|
||||||
msg: &str) {
|
msg: &str,
|
||||||
|
diagnostic: BuiltinLintDiagnostics) {
|
||||||
let early_lint = BufferedEarlyLint {
|
let early_lint = BufferedEarlyLint {
|
||||||
lint_id: LintId::of(lint),
|
lint_id: LintId::of(lint),
|
||||||
ast_id: id,
|
ast_id: id,
|
||||||
span: sp,
|
span: sp,
|
||||||
msg: msg.to_string(),
|
msg: msg.to_string(),
|
||||||
|
diagnostic
|
||||||
};
|
};
|
||||||
let arr = self.map.entry(id).or_insert(Vec::new());
|
let arr = self.map.entry(id).or_insert(Vec::new());
|
||||||
if !arr.contains(&early_lint) {
|
if !arr.contains(&early_lint) {
|
||||||
|
|
|
@ -16,6 +16,7 @@ use ich::Fingerprint;
|
||||||
|
|
||||||
use ich;
|
use ich;
|
||||||
use lint;
|
use lint;
|
||||||
|
use lint::builtin::BuiltinLintDiagnostics;
|
||||||
use middle::allocator::AllocatorKind;
|
use middle::allocator::AllocatorKind;
|
||||||
use middle::dependency_format;
|
use middle::dependency_format;
|
||||||
use session::search_paths::PathKind;
|
use session::search_paths::PathKind;
|
||||||
|
@ -341,7 +342,18 @@ impl Session {
|
||||||
sp: S,
|
sp: S,
|
||||||
msg: &str) {
|
msg: &str) {
|
||||||
match *self.buffered_lints.borrow_mut() {
|
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"),
|
None => bug!("can't buffer lints after HIR lowering"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue