@@ -33,6 +33,7 @@ use lint::{Level, LevelSource, Lint, LintId, LintPass, LintSource};
3333use lint:: { EarlyLintPassObject , LateLintPassObject } ;
3434use lint:: { Default , CommandLine , Node , Allow , Warn , Deny , Forbid } ;
3535use lint:: builtin;
36+ use rustc_serialize:: { Decoder , Decodable , Encoder , Encodable } ;
3637use util:: nodemap:: FxHashMap ;
3738
3839use std:: cmp;
@@ -82,7 +83,7 @@ pub struct LintStore {
8283
8384/// When you call `add_lint` on the session, you wind up storing one
8485/// of these, which records a "potential lint" at a particular point.
85- #[ derive( PartialEq ) ]
86+ #[ derive( PartialEq , RustcEncodable , RustcDecodable ) ]
8687pub struct EarlyLint {
8788 /// what lint is this? (e.g., `dead_code`)
8889 pub id : LintId ,
@@ -558,7 +559,7 @@ pub trait LintContext<'tcx>: Sized {
558559 self . lookup_and_emit ( lint, Some ( span) , msg) ;
559560 }
560561
561- fn early_lint ( & self , early_lint : EarlyLint ) {
562+ fn early_lint ( & self , early_lint : & EarlyLint ) {
562563 let span = early_lint. diagnostic . span . primary_span ( ) . expect ( "early lint w/o primary span" ) ;
563564 let mut err = self . struct_span_lint ( early_lint. id . lint ,
564565 span,
@@ -773,11 +774,10 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
773774
774775 // Output any lints that were previously added to the session.
775776 fn visit_id ( & mut self , id : ast:: NodeId ) {
776- if let Some ( lints) = self . sess ( ) . lints . borrow_mut ( ) . remove ( & id) {
777- debug ! ( "LateContext::visit_id: id={:?} lints={:?}" , id, lints) ;
778- for early_lint in lints {
779- self . early_lint ( early_lint) ;
780- }
777+ let lints = self . sess ( ) . lints . borrow_mut ( ) . take ( id) ;
778+ for early_lint in lints. iter ( ) . chain ( self . tables . lints . get ( id) ) {
779+ debug ! ( "LateContext::visit_id: id={:?} early_lint={:?}" , id, early_lint) ;
780+ self . early_lint ( early_lint) ;
781781 }
782782 }
783783
@@ -1232,7 +1232,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
12321232
12331233 // If we missed any lints added to the session, then there's a bug somewhere
12341234 // in the iteration code.
1235- for ( id, v) in tcx. sess . lints . borrow ( ) . iter ( ) {
1235+ if let Some ( ( id, v) ) = tcx. sess . lints . borrow ( ) . get_any ( ) {
12361236 for early_lint in v {
12371237 span_bug ! ( early_lint. diagnostic. span. clone( ) ,
12381238 "unprocessed lint {:?} at {}" ,
@@ -1250,10 +1250,9 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
12501250 // Visit the whole crate.
12511251 cx. with_lint_attrs ( & krate. attrs , |cx| {
12521252 // Lints may be assigned to the whole crate.
1253- if let Some ( lints) = cx. sess . lints . borrow_mut ( ) . remove ( & ast:: CRATE_NODE_ID ) {
1254- for early_lint in lints {
1255- cx. early_lint ( early_lint) ;
1256- }
1253+ let lints = cx. sess . lints . borrow_mut ( ) . take ( ast:: CRATE_NODE_ID ) ;
1254+ for early_lint in lints {
1255+ cx. early_lint ( & early_lint) ;
12571256 }
12581257
12591258 // since the root module isn't visited as an item (because it isn't an
@@ -1270,9 +1269,28 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
12701269
12711270 // If we missed any lints added to the session, then there's a bug somewhere
12721271 // in the iteration code.
1273- for ( _, v) in sess. lints . borrow ( ) . iter ( ) {
1272+ for ( _, v) in sess. lints . borrow ( ) . get_any ( ) {
12741273 for early_lint in v {
12751274 span_bug ! ( early_lint. diagnostic. span. clone( ) , "unprocessed lint {:?}" , early_lint) ;
12761275 }
12771276 }
12781277}
1278+
1279+ impl Encodable for LintId {
1280+ fn encode < S : Encoder > ( & self , s : & mut S ) -> Result < ( ) , S :: Error > {
1281+ s. emit_str ( & self . lint . name . to_lowercase ( ) )
1282+ }
1283+ }
1284+
1285+ impl Decodable for LintId {
1286+ #[ inline]
1287+ fn decode < D : Decoder > ( d : & mut D ) -> Result < LintId , D :: Error > {
1288+ let s = d. read_str ( ) ?;
1289+ ty:: tls:: with ( |tcx| {
1290+ match tcx. sess . lint_store . borrow ( ) . find_lint ( & s, tcx. sess , None ) {
1291+ Ok ( id) => Ok ( id) ,
1292+ Err ( _) => panic ! ( "invalid lint-id `{}`" , s) ,
1293+ }
1294+ } )
1295+ }
1296+ }
0 commit comments