Allow lint passes to be bound by TyCtxt
This commit is contained in:
parent
a594044533
commit
0126f7f3a9
10 changed files with 274 additions and 246 deletions
|
@ -50,6 +50,10 @@ use std::cell::Cell;
|
|||
use std::iter;
|
||||
use std::slice;
|
||||
|
||||
type EarlyLintPassFactory = dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync;
|
||||
type LateLintPassFactory =
|
||||
dyn for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx> + sync::Send + sync::Sync;
|
||||
|
||||
/// Information about the registered lints.
|
||||
///
|
||||
/// This is basically the subset of `Context` that we can
|
||||
|
@ -64,11 +68,11 @@ pub struct LintStore {
|
|||
/// interior mutability, we don't enforce this (and lints should, in theory,
|
||||
/// be compatible with being constructed more than once, though not
|
||||
/// necessarily in a sane manner. This is safe though.)
|
||||
pub pre_expansion_passes: Vec<Box<dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync>>,
|
||||
pub early_passes: Vec<Box<dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync>>,
|
||||
pub late_passes: Vec<Box<dyn Fn() -> LateLintPassObject + sync::Send + sync::Sync>>,
|
||||
pub pre_expansion_passes: Vec<Box<EarlyLintPassFactory>>,
|
||||
pub early_passes: Vec<Box<EarlyLintPassFactory>>,
|
||||
pub late_passes: Vec<Box<LateLintPassFactory>>,
|
||||
/// This is unique in that we construct them per-module, so not once.
|
||||
pub late_module_passes: Vec<Box<dyn Fn() -> LateLintPassObject + sync::Send + sync::Sync>>,
|
||||
pub late_module_passes: Vec<Box<LateLintPassFactory>>,
|
||||
|
||||
/// Lints indexed by name.
|
||||
by_name: FxHashMap<String, TargetLint>,
|
||||
|
@ -186,14 +190,20 @@ impl LintStore {
|
|||
|
||||
pub fn register_late_pass(
|
||||
&mut self,
|
||||
pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync,
|
||||
pass: impl for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx>
|
||||
+ 'static
|
||||
+ sync::Send
|
||||
+ sync::Sync,
|
||||
) {
|
||||
self.late_passes.push(Box::new(pass));
|
||||
}
|
||||
|
||||
pub fn register_late_mod_pass(
|
||||
&mut self,
|
||||
pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync,
|
||||
pass: impl for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx>
|
||||
+ 'static
|
||||
+ sync::Send
|
||||
+ sync::Sync,
|
||||
) {
|
||||
self.late_module_passes.push(Box::new(pass));
|
||||
}
|
||||
|
@ -558,7 +568,7 @@ pub trait LintPassObject: Sized {}
|
|||
|
||||
impl LintPassObject for EarlyLintPassObject {}
|
||||
|
||||
impl LintPassObject for LateLintPassObject {}
|
||||
impl LintPassObject for LateLintPassObject<'_> {}
|
||||
|
||||
pub trait LintContext: Sized {
|
||||
type PassObject: LintPassObject;
|
||||
|
@ -949,8 +959,8 @@ impl<'a> EarlyContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl LintContext for LateContext<'_> {
|
||||
type PassObject = LateLintPassObject;
|
||||
impl<'tcx> LintContext for LateContext<'tcx> {
|
||||
type PassObject = LateLintPassObject<'tcx>;
|
||||
|
||||
/// Gets the overall compiler `Session` object.
|
||||
fn sess(&self) -> &Session {
|
||||
|
|
|
@ -306,12 +306,12 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
|
|||
}
|
||||
}
|
||||
|
||||
struct LateLintPassObjects<'a> {
|
||||
lints: &'a mut [LateLintPassObject],
|
||||
struct LateLintPassObjects<'a, 'tcx> {
|
||||
lints: &'a mut [LateLintPassObject<'tcx>],
|
||||
}
|
||||
|
||||
#[allow(rustc::lint_pass_impl_without_macro)]
|
||||
impl LintPass for LateLintPassObjects<'_> {
|
||||
impl LintPass for LateLintPassObjects<'_, '_> {
|
||||
fn name(&self) -> &'static str {
|
||||
panic!()
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ macro_rules! expand_late_lint_pass_impl_methods {
|
|||
|
||||
macro_rules! late_lint_pass_impl {
|
||||
([], [$hir:tt], $methods:tt) => {
|
||||
impl<$hir> LateLintPass<$hir> for LateLintPassObjects<'_> {
|
||||
impl<$hir> LateLintPass<$hir> for LateLintPassObjects<'_, $hir> {
|
||||
expand_late_lint_pass_impl_methods!([$hir], $methods);
|
||||
}
|
||||
};
|
||||
|
@ -382,7 +382,7 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx>>(
|
|||
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)()).collect();
|
||||
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[..] });
|
||||
|
@ -418,7 +418,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)()).collect::<Vec<_>>();
|
||||
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() {
|
||||
|
@ -434,7 +435,7 @@ fn late_lint_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints
|
|||
}
|
||||
|
||||
let mut passes: Vec<_> =
|
||||
unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)()).collect();
|
||||
unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)(tcx)).collect();
|
||||
|
||||
for pass in &mut passes {
|
||||
tcx.sess.prof.extra_verbose_generic_activity("run_late_module_lint", pass.name()).run(
|
||||
|
|
|
@ -260,26 +260,41 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
|
|||
)
|
||||
}
|
||||
|
||||
macro_rules! register_pass {
|
||||
macro_rules! register_early_pass {
|
||||
($method:ident, $ty:ident, $constructor:expr) => {
|
||||
store.register_lints(&$ty::get_lints());
|
||||
store.$method(|| Box::new($constructor));
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! register_passes {
|
||||
macro_rules! register_late_pass {
|
||||
($method:ident, $ty:ident, $constructor:expr) => {
|
||||
store.register_lints(&$ty::get_lints());
|
||||
store.$method(|_| Box::new($constructor));
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! register_early_passes {
|
||||
($method:ident, [$($passes:ident: $constructor:expr,)*]) => (
|
||||
$(
|
||||
register_pass!($method, $passes, $constructor);
|
||||
register_early_pass!($method, $passes, $constructor);
|
||||
)*
|
||||
)
|
||||
}
|
||||
|
||||
macro_rules! register_late_passes {
|
||||
($method:ident, [$($passes:ident: $constructor:expr,)*]) => (
|
||||
$(
|
||||
register_late_pass!($method, $passes, $constructor);
|
||||
)*
|
||||
)
|
||||
}
|
||||
|
||||
if no_interleave_lints {
|
||||
pre_expansion_lint_passes!(register_passes, register_pre_expansion_pass);
|
||||
early_lint_passes!(register_passes, register_early_pass);
|
||||
late_lint_passes!(register_passes, register_late_pass);
|
||||
late_lint_mod_passes!(register_passes, register_late_mod_pass);
|
||||
pre_expansion_lint_passes!(register_early_passes, register_pre_expansion_pass);
|
||||
early_lint_passes!(register_early_passes, register_early_pass);
|
||||
late_lint_passes!(register_late_passes, register_late_pass);
|
||||
late_lint_mod_passes!(register_late_passes, register_late_mod_pass);
|
||||
} else {
|
||||
store.register_lints(&BuiltinCombinedPreExpansionLintPass::get_lints());
|
||||
store.register_lints(&BuiltinCombinedEarlyLintPass::get_lints());
|
||||
|
@ -510,19 +525,19 @@ fn register_internals(store: &mut LintStore) {
|
|||
store.register_lints(&LintPassImpl::get_lints());
|
||||
store.register_early_pass(|| Box::new(LintPassImpl));
|
||||
store.register_lints(&DefaultHashTypes::get_lints());
|
||||
store.register_late_pass(|| Box::new(DefaultHashTypes));
|
||||
store.register_late_pass(|_| Box::new(DefaultHashTypes));
|
||||
store.register_lints(&QueryStability::get_lints());
|
||||
store.register_late_pass(|| Box::new(QueryStability));
|
||||
store.register_late_pass(|_| Box::new(QueryStability));
|
||||
store.register_lints(&ExistingDocKeyword::get_lints());
|
||||
store.register_late_pass(|| Box::new(ExistingDocKeyword));
|
||||
store.register_late_pass(|_| Box::new(ExistingDocKeyword));
|
||||
store.register_lints(&TyTyKind::get_lints());
|
||||
store.register_late_pass(|| Box::new(TyTyKind));
|
||||
store.register_late_pass(|_| Box::new(TyTyKind));
|
||||
store.register_lints(&Diagnostics::get_lints());
|
||||
store.register_late_pass(|| Box::new(Diagnostics));
|
||||
store.register_late_pass(|_| Box::new(Diagnostics));
|
||||
store.register_lints(&BadOptAccess::get_lints());
|
||||
store.register_late_pass(|| Box::new(BadOptAccess));
|
||||
store.register_late_pass(|_| Box::new(BadOptAccess));
|
||||
store.register_lints(&PassByValue::get_lints());
|
||||
store.register_late_pass(|| Box::new(PassByValue));
|
||||
store.register_late_pass(|_| Box::new(PassByValue));
|
||||
// FIXME(davidtwco): deliberately do not include `UNTRANSLATABLE_DIAGNOSTIC` and
|
||||
// `DIAGNOSTIC_OUTSIDE_OF_IMPL` here because `-Wrustc::internal` is provided to every crate and
|
||||
// these lints will trigger all of the time - change this once migration to diagnostic structs
|
||||
|
|
|
@ -244,4 +244,4 @@ macro_rules! declare_combined_early_lint_pass {
|
|||
|
||||
/// A lint pass boxed up as a trait object.
|
||||
pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + 'static>;
|
||||
pub type LateLintPassObject = Box<dyn for<'tcx> LateLintPass<'tcx> + sync::Send + 'static>;
|
||||
pub type LateLintPassObject<'tcx> = Box<dyn LateLintPass<'tcx> + sync::Send + 'tcx>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue