@@ -29,6 +29,7 @@ use self::TargetLint::*;
2929use std:: slice;
3030use lint:: { EarlyLintPassObject , LateLintPassObject } ;
3131use lint:: { Level , Lint , LintId , LintPass , LintBuffer } ;
32+ use lint:: builtin:: BuiltinLintDiagnostics ;
3233use lint:: levels:: { LintLevelSets , LintLevelsBuilder } ;
3334use middle:: privacy:: AccessLevels ;
3435use rustc_serialize:: { Decoder , Decodable , Encoder , Encodable } ;
@@ -92,14 +93,19 @@ 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
98100/// to `register_future_incompatible` in `librustc_lint/lib.rs` for
99101/// guidelines.
100102pub struct FutureIncompatibleInfo {
101103 pub id : LintId ,
102- pub reference : & ' static str // e.g., a URL for an issue/PR/RFC or error code
104+ /// e.g., a URL for an issue/PR/RFC or error code
105+ pub reference : & ' static str ,
106+ /// If this is an epoch fixing lint, the epoch in which
107+ /// this lint becomes obsolete
108+ pub epoch : Option < config:: Epoch > ,
103109}
104110
105111/// The target of the `by_name` map, which accounts for renaming/deprecation.
@@ -194,11 +200,24 @@ impl LintStore {
194200 pub fn register_future_incompatible ( & mut self ,
195201 sess : Option < & Session > ,
196202 lints : Vec < FutureIncompatibleInfo > ) {
197- let ids = lints. iter ( ) . map ( |f| f. id ) . collect ( ) ;
198- self . register_group ( sess, false , "future_incompatible" , ids) ;
199- for info in lints {
200- self . future_incompatible . insert ( info. id , info) ;
203+
204+ for epoch in config:: ALL_EPOCHS {
205+ let lints = lints. iter ( ) . filter ( |f| f. epoch == Some ( * epoch) ) . map ( |f| f. id )
206+ . collect :: < Vec < _ > > ( ) ;
207+ if !lints. is_empty ( ) {
208+ self . register_group ( sess, false , epoch. lint_name ( ) , lints)
209+ }
201210 }
211+
212+ let mut future_incompatible = vec ! [ ] ;
213+ for lint in lints {
214+ future_incompatible. push ( lint. id ) ;
215+ self . future_incompatible . insert ( lint. id , lint) ;
216+ }
217+
218+ self . register_group ( sess, false , "future_incompatible" , future_incompatible) ;
219+
220+
202221 }
203222
204223 pub fn future_incompatible ( & self , id : LintId ) -> Option < & FutureIncompatibleInfo > {
@@ -429,6 +448,16 @@ pub trait LintContext<'tcx>: Sized {
429448 self . lookup ( lint, span, msg) . emit ( ) ;
430449 }
431450
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+
432461 fn lookup < S : Into < MultiSpan > > ( & self ,
433462 lint : & ' static Lint ,
434463 span : Option < S > ,
@@ -499,9 +528,10 @@ impl<'a> EarlyContext<'a> {
499528
500529 fn check_id ( & mut self , id : ast:: NodeId ) {
501530 for early_lint in self . buffered . take ( id) {
502- self . lookup_and_emit ( early_lint. lint_id . lint ,
503- Some ( early_lint. span . clone ( ) ) ,
504- & 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 ) ;
505535 }
506536 }
507537}
@@ -1054,7 +1084,7 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
10541084 if !sess. opts . actually_rustdoc {
10551085 for ( _id, lints) in cx. buffered . map {
10561086 for early_lint in lints {
1057- span_bug ! ( early_lint. span, "failed to process buffered lint here" ) ;
1087+ sess . delay_span_bug ( early_lint. span , "failed to process buffered lint here" ) ;
10581088 }
10591089 }
10601090 }
0 commit comments