@@ -29,6 +29,7 @@ use self::TargetLint::*;
29
29
use std:: slice;
30
30
use lint:: { EarlyLintPassObject , LateLintPassObject } ;
31
31
use lint:: { Level , Lint , LintId , LintPass , LintBuffer } ;
32
+ use lint:: builtin:: BuiltinLintDiagnostics ;
32
33
use lint:: levels:: { LintLevelSets , LintLevelsBuilder } ;
33
34
use middle:: privacy:: AccessLevels ;
34
35
use rustc_serialize:: { Decoder , Decodable , Encoder , Encodable } ;
@@ -92,14 +93,19 @@ pub struct BufferedEarlyLint {
92
93
pub ast_id : ast:: NodeId ,
93
94
pub span : MultiSpan ,
94
95
pub msg : String ,
96
+ pub diagnostic : BuiltinLintDiagnostics ,
95
97
}
96
98
97
99
/// Extra information for a future incompatibility lint. See the call
98
100
/// to `register_future_incompatible` in `librustc_lint/lib.rs` for
99
101
/// guidelines.
100
102
pub struct FutureIncompatibleInfo {
101
103
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 > ,
103
109
}
104
110
105
111
/// The target of the `by_name` map, which accounts for renaming/deprecation.
@@ -194,11 +200,24 @@ impl LintStore {
194
200
pub fn register_future_incompatible ( & mut self ,
195
201
sess : Option < & Session > ,
196
202
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
+ }
201
210
}
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
+
202
221
}
203
222
204
223
pub fn future_incompatible ( & self , id : LintId ) -> Option < & FutureIncompatibleInfo > {
@@ -429,6 +448,16 @@ pub trait LintContext<'tcx>: Sized {
429
448
self . lookup ( lint, span, msg) . emit ( ) ;
430
449
}
431
450
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
+
432
461
fn lookup < S : Into < MultiSpan > > ( & self ,
433
462
lint : & ' static Lint ,
434
463
span : Option < S > ,
@@ -499,9 +528,10 @@ impl<'a> EarlyContext<'a> {
499
528
500
529
fn check_id ( & mut self , id : ast:: NodeId ) {
501
530
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 ) ;
505
535
}
506
536
}
507
537
}
@@ -1054,7 +1084,7 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
1054
1084
if !sess. opts . actually_rustdoc {
1055
1085
for ( _id, lints) in cx. buffered . map {
1056
1086
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" ) ;
1058
1088
}
1059
1089
}
1060
1090
}
0 commit comments