summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_lint/src/late.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_lint/src/late.rs')
-rw-r--r--compiler/rustc_lint/src/late.rs132
1 files changed, 26 insertions, 106 deletions
diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs
index 303fcb1a1..8a50cb1f1 100644
--- a/compiler/rustc_lint/src/late.rs
+++ b/compiler/rustc_lint/src/late.rs
@@ -23,12 +23,10 @@ use rustc_hir::intravisit as hir_visit;
use rustc_hir::intravisit::Visitor;
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{self, TyCtxt};
-use rustc_session::lint::LintPass;
use rustc_span::Span;
use std::any::Any;
use std::cell::Cell;
-use std::slice;
/// Extract the `LintStore` from the query context.
/// This function exists because we've erased `LintStore` as `dyn Any` in the context.
@@ -38,15 +36,17 @@ pub fn unerased_lint_store(tcx: TyCtxt<'_>) -> &LintStore {
}
macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({
- $cx.pass.$f(&$cx.context, $($args),*);
+ for pass in $cx.passes.iter_mut() {
+ pass.$f(&$cx.context, $($args),*);
+ }
}) }
-struct LateContextAndPass<'tcx, T: LateLintPass<'tcx>> {
+struct LateContextAndPasses<'tcx> {
context: LateContext<'tcx>,
- pass: T,
+ passes: Vec<LateLintPassObject<'tcx>>,
}
-impl<'tcx, T: LateLintPass<'tcx>> LateContextAndPass<'tcx, T> {
+impl<'tcx> LateContextAndPasses<'tcx> {
/// Merge the lints specified by any lint attributes into the
/// current lint context, call the provided function, then reset the
/// lints in effect to their previous state.
@@ -82,7 +82,7 @@ impl<'tcx, T: LateLintPass<'tcx>> LateContextAndPass<'tcx, T> {
}
}
-impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPass<'tcx, T> {
+impl<'tcx> hir_visit::Visitor<'tcx> for LateContextAndPasses<'tcx> {
type NestedFilter = nested_filter::All;
/// Because lints are scoped lexically, we want to walk nested
@@ -205,7 +205,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
}
fn visit_variant(&mut self, v: &'tcx hir::Variant<'tcx>) {
- self.with_lint_attrs(v.id, |cx| {
+ self.with_lint_attrs(v.hir_id, |cx| {
lint_callback!(cx, check_variant, v);
hir_visit::walk_variant(cx, v);
})
@@ -292,7 +292,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
hir_visit::walk_lifetime(self, lt);
}
- fn visit_path(&mut self, p: &'tcx hir::Path<'tcx>, id: hir::HirId) {
+ fn visit_path(&mut self, p: &hir::Path<'tcx>, id: hir::HirId) {
lint_callback!(self, check_path, p, id);
hir_visit::walk_path(self, p);
}
@@ -302,57 +302,28 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
}
}
-struct LateLintPassObjects<'a, 'tcx> {
- lints: &'a mut [LateLintPassObject<'tcx>],
-}
-
-#[allow(rustc::lint_pass_impl_without_macro)]
-impl LintPass for LateLintPassObjects<'_, '_> {
- fn name(&self) -> &'static str {
- panic!()
- }
-}
-
-macro_rules! expand_late_lint_pass_impl_methods {
- ([$hir:tt], [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
- $(fn $name(&mut self, context: &LateContext<$hir>, $($param: $arg),*) {
- for obj in self.lints.iter_mut() {
- obj.$name(context, $($param),*);
- }
- })*
- )
-}
-
-macro_rules! late_lint_pass_impl {
- ([], [$hir:tt], $methods:tt) => {
- impl<$hir> LateLintPass<$hir> for LateLintPassObjects<'_, $hir> {
- expand_late_lint_pass_impl_methods!([$hir], $methods);
- }
- };
-}
-
-crate::late_lint_methods!(late_lint_pass_impl, [], ['tcx]);
-
-fn late_lint_mod_pass<'tcx, T: LateLintPass<'tcx>>(
+pub(super) fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>(
tcx: TyCtxt<'tcx>,
module_def_id: LocalDefId,
- pass: T,
+ builtin_lints: T,
) {
- let effective_visibilities = &tcx.effective_visibilities(());
-
let context = LateContext {
tcx,
enclosing_body: None,
cached_typeck_results: Cell::new(None),
param_env: ty::ParamEnv::empty(),
- effective_visibilities,
+ effective_visibilities: &tcx.effective_visibilities(()),
lint_store: unerased_lint_store(tcx),
last_node_with_lint_attrs: tcx.hir().local_def_id_to_hir_id(module_def_id),
generics: None,
only_module: true,
};
- let mut cx = LateContextAndPass { context, pass };
+ let mut passes: Vec<_> =
+ unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)(tcx)).collect();
+ passes.push(Box::new(builtin_lints));
+
+ let mut cx = LateContextAndPasses { context, passes };
let (module, _span, hir_id) = tcx.hir().get_module(module_def_id);
cx.process_mod(module, hir_id);
@@ -365,46 +336,28 @@ fn late_lint_mod_pass<'tcx, T: LateLintPass<'tcx>>(
}
}
-pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx>>(
- tcx: TyCtxt<'tcx>,
- module_def_id: LocalDefId,
- builtin_lints: T,
-) {
- if tcx.sess.opts.unstable_opts.no_interleave_lints {
- // These passes runs in late_lint_crate with -Z no_interleave_lints
- return;
- }
-
- late_lint_mod_pass(tcx, module_def_id, builtin_lints);
-
- let mut passes: Vec<_> =
- unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)(tcx)).collect();
-
- if !passes.is_empty() {
- late_lint_mod_pass(tcx, module_def_id, LateLintPassObjects { lints: &mut passes[..] });
- }
-}
-
-fn late_lint_pass_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, pass: T) {
- let effective_visibilities = &tcx.effective_visibilities(());
-
+fn late_lint_crate<'tcx, T: LateLintPass<'tcx> + 'tcx>(tcx: TyCtxt<'tcx>, builtin_lints: T) {
let context = LateContext {
tcx,
enclosing_body: None,
cached_typeck_results: Cell::new(None),
param_env: ty::ParamEnv::empty(),
- effective_visibilities,
+ effective_visibilities: &tcx.effective_visibilities(()),
lint_store: unerased_lint_store(tcx),
last_node_with_lint_attrs: hir::CRATE_HIR_ID,
generics: None,
only_module: false,
};
- let mut cx = LateContextAndPass { context, pass };
+ let mut passes =
+ unerased_lint_store(tcx).late_passes.iter().map(|p| (p)(tcx)).collect::<Vec<_>>();
+ passes.push(Box::new(builtin_lints));
+
+ let mut cx = LateContextAndPasses { context, passes };
// Visit the whole crate.
cx.with_lint_attrs(hir::CRATE_HIR_ID, |cx| {
- // since the root module isn't visited as an item (because it isn't an
+ // Since the root module isn't visited as an item (because it isn't an
// item), warn for it here.
lint_callback!(cx, check_crate,);
tcx.hir().walk_toplevel_module(cx);
@@ -413,41 +366,8 @@ fn late_lint_pass_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, pass: T)
})
}
-fn late_lint_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints: T) {
- let mut passes =
- unerased_lint_store(tcx).late_passes.iter().map(|p| (p)(tcx)).collect::<Vec<_>>();
-
- if !tcx.sess.opts.unstable_opts.no_interleave_lints {
- if !passes.is_empty() {
- late_lint_pass_crate(tcx, LateLintPassObjects { lints: &mut passes[..] });
- }
-
- late_lint_pass_crate(tcx, builtin_lints);
- } else {
- for pass in &mut passes {
- tcx.sess.prof.verbose_generic_activity_with_arg("run_late_lint", pass.name()).run(
- || {
- late_lint_pass_crate(tcx, LateLintPassObjects { lints: slice::from_mut(pass) });
- },
- );
- }
-
- let mut passes: Vec<_> =
- unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)(tcx)).collect();
-
- for pass in &mut passes {
- tcx.sess
- .prof
- .verbose_generic_activity_with_arg("run_late_module_lint", pass.name())
- .run(|| {
- late_lint_pass_crate(tcx, LateLintPassObjects { lints: slice::from_mut(pass) });
- });
- }
- }
-}
-
/// Performs lint checking on a crate.
-pub fn check_crate<'tcx, T: LateLintPass<'tcx>>(
+pub fn check_crate<'tcx, T: LateLintPass<'tcx> + 'tcx>(
tcx: TyCtxt<'tcx>,
builtin_lints: impl FnOnce() -> T + Send,
) {