Skip to content

Commit bd29696

Browse files
committed
Add ability for hardwired lints to operate on the diagnostic builder
1 parent 3eeabe7 commit bd29696

File tree

4 files changed

+59
-5
lines changed

4 files changed

+59
-5
lines changed

src/librustc/lint/builtin.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@
1414
//! compiler code, rather than using their own custom pass. Those
1515
//! lints are all available in `rustc_lint::builtin`.
1616
17+
use errors::DiagnosticBuilder;
1718
use lint::{LintPass, LateLintPass, LintArray};
19+
use session::Session;
1820
use session::config::Epoch;
21+
use syntax::codemap::Span;
1922

2023
declare_lint! {
2124
pub CONST_ERR,
@@ -312,4 +315,27 @@ impl LintPass for HardwiredLints {
312315
}
313316
}
314317

318+
// this could be a closure, but then implementing derive traits
319+
// becomes hacky (and it gets allocated)
320+
#[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)]
321+
pub enum BuiltinLintDiagnostics {
322+
Normal,
323+
BareTraitObject(Span)
324+
}
325+
326+
impl BuiltinLintDiagnostics {
327+
pub fn run(self, sess: &Session, db: &mut DiagnosticBuilder) {
328+
match self {
329+
BuiltinLintDiagnostics::Normal => (),
330+
BuiltinLintDiagnostics::BareTraitObject(span) => {
331+
let sugg = match sess.codemap().span_to_snippet(span) {
332+
Ok(s) => format!("dyn {}", s),
333+
Err(_) => format!("dyn <type>")
334+
};
335+
db.span_suggestion(span, "use `dyn`", sugg);
336+
}
337+
}
338+
}
339+
}
340+
315341
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {}

src/librustc/lint/context.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use self::TargetLint::*;
2929
use std::slice;
3030
use lint::{EarlyLintPassObject, LateLintPassObject};
3131
use lint::{Level, Lint, LintId, LintPass, LintBuffer};
32+
use lint::builtin::BuiltinLintDiagnostics;
3233
use lint::levels::{LintLevelSets, LintLevelsBuilder};
3334
use middle::privacy::AccessLevels;
3435
use rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
@@ -92,6 +93,7 @@ pub struct BufferedEarlyLint {
9293
pub ast_id: ast::NodeId,
9394
pub span: MultiSpan,
9495
pub msg: String,
96+
pub diagnostic: BuiltinLintDiagnostics,
9597
}
9698

9799
/// Extra information for a future incompatibility lint. See the call
@@ -446,6 +448,16 @@ pub trait LintContext<'tcx>: Sized {
446448
self.lookup(lint, span, msg).emit();
447449
}
448450

451+
fn lookup_and_emit_with_diagnostics<S: Into<MultiSpan>>(&self,
452+
lint: &'static Lint,
453+
span: Option<S>,
454+
msg: &str,
455+
diagnostic: BuiltinLintDiagnostics) {
456+
let mut db = self.lookup(lint, span, msg);
457+
diagnostic.run(self.sess(), &mut db);
458+
db.emit();
459+
}
460+
449461
fn lookup<S: Into<MultiSpan>>(&self,
450462
lint: &'static Lint,
451463
span: Option<S>,
@@ -516,9 +528,10 @@ impl<'a> EarlyContext<'a> {
516528

517529
fn check_id(&mut self, id: ast::NodeId) {
518530
for early_lint in self.buffered.take(id) {
519-
self.lookup_and_emit(early_lint.lint_id.lint,
520-
Some(early_lint.span.clone()),
521-
&early_lint.msg);
531+
self.lookup_and_emit_with_diagnostics(early_lint.lint_id.lint,
532+
Some(early_lint.span.clone()),
533+
&early_lint.msg,
534+
early_lint.diagnostic);
522535
}
523536
}
524537
}

src/librustc/lint/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use errors::{DiagnosticBuilder, DiagnosticId};
3737
use hir::def_id::{CrateNum, LOCAL_CRATE};
3838
use hir::intravisit::{self, FnKind};
3939
use hir;
40+
use lint::builtin::BuiltinLintDiagnostics;
4041
use session::{config, Session, DiagnosticMessageId};
4142
use std::hash;
4243
use syntax::ast;
@@ -399,12 +400,14 @@ impl LintBuffer {
399400
lint: &'static Lint,
400401
id: ast::NodeId,
401402
sp: MultiSpan,
402-
msg: &str) {
403+
msg: &str,
404+
diagnostic: BuiltinLintDiagnostics) {
403405
let early_lint = BufferedEarlyLint {
404406
lint_id: LintId::of(lint),
405407
ast_id: id,
406408
span: sp,
407409
msg: msg.to_string(),
410+
diagnostic
408411
};
409412
let arr = self.map.entry(id).or_insert(Vec::new());
410413
if !arr.contains(&early_lint) {

src/librustc/session/mod.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use ich::Fingerprint;
1616

1717
use ich;
1818
use lint;
19+
use lint::builtin::BuiltinLintDiagnostics;
1920
use middle::allocator::AllocatorKind;
2021
use middle::dependency_format;
2122
use session::search_paths::PathKind;
@@ -341,7 +342,18 @@ impl Session {
341342
sp: S,
342343
msg: &str) {
343344
match *self.buffered_lints.borrow_mut() {
344-
Some(ref mut buffer) => buffer.add_lint(lint, id, sp.into(), msg),
345+
Some(ref mut buffer) => buffer.add_lint(lint, id, sp.into(),
346+
msg, BuiltinLintDiagnostics::Normal),
347+
None => bug!("can't buffer lints after HIR lowering"),
348+
}
349+
}
350+
351+
pub fn buffer_lint_with_diagnostic<S: Into<MultiSpan>>(&self,
352+
lint: &'static lint::Lint, id: ast::NodeId, sp: S,
353+
msg: &str, diagnostic: BuiltinLintDiagnostics) {
354+
match *self.buffered_lints.borrow_mut() {
355+
Some(ref mut buffer) => buffer.add_lint(lint, id, sp.into(),
356+
msg, diagnostic),
345357
None => bug!("can't buffer lints after HIR lowering"),
346358
}
347359
}

0 commit comments

Comments
 (0)