diff options
| author | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-06-11 08:48:15 +0200 |
|---|---|---|
| committer | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2019-03-25 23:00:34 +0100 |
| commit | 7e156c2066bd9bf3a3d076ed32dd0d7b217c5857 (patch) | |
| tree | 5406cd654488f8f90814a432a736c1126cd05878 /src/librustc | |
| parent | 4c27fb19ba15a2e45485e601a79914c6280196b0 (diff) | |
| download | rust-7e156c2066bd9bf3a3d076ed32dd0d7b217c5857.tar.gz rust-7e156c2066bd9bf3a3d076ed32dd0d7b217c5857.zip | |
Make some lints incremental
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/dep_graph/dep_node.rs | 1 | ||||
| -rw-r--r-- | src/librustc/hir/map/mod.rs | 8 | ||||
| -rw-r--r-- | src/librustc/lint/context.rs | 80 | ||||
| -rw-r--r-- | src/librustc/lint/mod.rs | 1 | ||||
| -rw-r--r-- | src/librustc/ty/query/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc/ty/query/plumbing.rs | 1 |
6 files changed, 80 insertions, 13 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 43e865ad089..792b0ce7146 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -474,6 +474,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [] UnsafetyCheckResult(DefId), [] UnsafeDeriveOnReprPacked(DefId), + [] LintMod(DefId), [] CheckModAttrs(DefId), [] CheckModLoops(DefId), [] CheckModUnstableApiUsage(DefId), diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index d810a9310c5..56c3c71339f 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -580,17 +580,17 @@ impl<'hir> Map<'hir> { &self.forest.krate.attrs } - pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, NodeId) - { + pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, HirId) { let node_id = self.as_local_node_id(module).unwrap(); + let hir_id = self.node_to_hir_id(node_id); self.read(node_id); match self.find_entry(node_id).unwrap().node { Node::Item(&Item { span, node: ItemKind::Mod(ref m), .. - }) => (m, span, node_id), - Node::Crate => (&self.forest.krate.module, self.forest.krate.span, node_id), + }) => (m, span, hir_id), + Node::Crate => (&self.forest.krate.module, self.forest.krate.span, hir_id), _ => panic!("not a module") } } diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 94f1d9c2710..6df3409d080 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -27,6 +27,7 @@ use crate::rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use crate::session::{config, early_error, Session}; use crate::ty::{self, TyCtxt, Ty}; use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; +use crate::ty::query::Providers; use crate::util::nodemap::FxHashMap; use crate::util::common::time; @@ -36,7 +37,7 @@ use syntax::edition; use syntax_pos::{MultiSpan, Span, symbol::{LocalInternedString, Symbol}}; use errors::DiagnosticBuilder; use crate::hir; -use crate::hir::def_id::LOCAL_CRATE; +use crate::hir::def_id::{DefId, LOCAL_CRATE}; use crate::hir::intravisit as hir_visit; use syntax::util::lev_distance::find_best_match_for_name; use syntax::visit as ast_visit; @@ -55,6 +56,7 @@ pub struct LintStore { pre_expansion_passes: Option<Vec<EarlyLintPassObject>>, early_passes: Option<Vec<EarlyLintPassObject>>, late_passes: Option<Vec<LateLintPassObject>>, + late_module_passes: Option<Vec<LateLintPassObject>>, /// Lints indexed by name. by_name: FxHashMap<String, TargetLint>, @@ -150,6 +152,7 @@ impl LintStore { pre_expansion_passes: Some(vec![]), early_passes: Some(vec![]), late_passes: Some(vec![]), + late_module_passes: Some(vec![]), by_name: Default::default(), future_incompatible: Default::default(), lint_groups: Default::default(), @@ -199,9 +202,14 @@ impl LintStore { pub fn register_late_pass(&mut self, sess: Option<&Session>, from_plugin: bool, + per_module: bool, pass: LateLintPassObject) { self.push_pass(sess, from_plugin, &pass); - self.late_passes.as_mut().unwrap().push(pass); + if per_module { + self.late_module_passes.as_mut().unwrap().push(pass); + } else { + self.late_passes.as_mut().unwrap().push(pass); + } } // Helper method for register_early/late_pass @@ -508,6 +516,7 @@ pub struct LateContext<'a, 'tcx: 'a> { pub tcx: TyCtxt<'a, 'tcx, 'tcx>, /// Side-tables for the body we are in. + // FIXME: Make this lazy to avoid running the TypeckTables query? pub tables: &'a ty::TypeckTables<'tcx>, /// Parameter environment for the item we are in. @@ -523,6 +532,9 @@ pub struct LateContext<'a, 'tcx: 'a> { /// Generic type parameters in scope for the item we are in. pub generics: Option<&'tcx hir::Generics>, + + /// We are only looking at one module + only_module: bool, } /// Context for lint checking of the AST, after expansion, before lowering to @@ -803,6 +815,12 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> { pub fn current_lint_root(&self) -> hir::HirId { self.last_node_with_lint_attrs } + + fn process_mod(&mut self, m: &'tcx hir::Mod, s: Span, n: hir::HirId) { + run_lints!(self, check_mod, m, s, n); + hir_visit::walk_mod(self, m, n); + run_lints!(self, check_mod_post, m, s, n); + } } impl<'a, 'tcx> LayoutOf for LateContext<'a, 'tcx> { @@ -934,9 +952,9 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> { } fn visit_mod(&mut self, m: &'tcx hir::Mod, s: Span, n: hir::HirId) { - run_lints!(self, check_mod, m, s, n); - hir_visit::walk_mod(self, m, n); - run_lints!(self, check_mod_post, m, s, n); + if !self.only_module { + self.process_mod(m, s, n); + } } fn visit_local(&mut self, l: &'tcx hir::Local) { @@ -1203,11 +1221,43 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> } } +pub fn lint_mod<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { + let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE); -/// Performs lint checking on a crate. -/// -/// Consumes the `lint_store` field of the `Session`. -pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { + let store = &tcx.sess.lint_store; + let passes = store.borrow_mut().late_module_passes.take(); + + let mut cx = LateContext { + tcx, + tables: &ty::TypeckTables::empty(None), + param_env: ty::ParamEnv::empty(), + access_levels, + lint_sess: LintSession { + lints: store.borrow(), + passes, + }, + last_node_with_lint_attrs: tcx.hir().as_local_hir_id(module_def_id).unwrap(), + generics: None, + only_module: true, + }; + + let (module, span, hir_id) = tcx.hir().get_module(module_def_id); + cx.process_mod(module, span, hir_id); + + // Put the lint store levels and passes back in the session. + let passes = cx.lint_sess.passes; + drop(cx.lint_sess.lints); + store.borrow_mut().late_module_passes = passes; +} + +pub(crate) fn provide(providers: &mut Providers<'_>) { + *providers = Providers { + lint_mod, + ..*providers + }; +} + +fn lint_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE); let krate = tcx.hir().krate(); @@ -1225,6 +1275,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { }, last_node_with_lint_attrs: hir::CRATE_HIR_ID, generics: None, + only_module: false, }; // Visit the whole crate. @@ -1244,6 +1295,17 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.sess.lint_store.borrow_mut().late_passes = passes; } +/// Performs lint checking on a crate. +pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { + // Run per-module lints + for &module in tcx.hir().krate().modules.keys() { + tcx.ensure().lint_mod(tcx.hir().local_def_id(module)); + } + + // Run whole crate non-incremental lints + lint_crate(tcx); +} + struct EarlyLintPassObjects<'a> { lints: &'a mut [EarlyLintPassObject], } diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index ae44210bcff..cf1c5d50000 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -824,6 +824,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'a, 'tcx> { pub fn provide(providers: &mut Providers<'_>) { providers.lint_levels = lint_levels; + context::provide(providers); } /// Returns whether `span` originates in a foreign crate's external macro. diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index a2d7815920e..86299b29f48 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -245,6 +245,8 @@ rustc_query_append! { [define_queries!][ <'tcx> }, Other { + [] fn lint_mod: LintMod(DefId) -> (), + /// Checks the attributes in the module [] fn check_mod_attrs: CheckModAttrs(DefId) -> (), diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index e82e09c2997..099fd352680 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1272,6 +1272,7 @@ pub fn force_from_dep_node<'tcx>( DepKind::MirBorrowCheck => { force!(mir_borrowck, def_id!()); } DepKind::UnsafetyCheckResult => { force!(unsafety_check_result, def_id!()); } DepKind::UnsafeDeriveOnReprPacked => { force!(unsafe_derive_on_repr_packed, def_id!()); } + DepKind::LintMod => { force!(lint_mod, def_id!()); } DepKind::CheckModAttrs => { force!(check_mod_attrs, def_id!()); } DepKind::CheckModLoops => { force!(check_mod_loops, def_id!()); } DepKind::CheckModUnstableApiUsage => { force!(check_mod_unstable_api_usage, def_id!()); } |
