Skip to content

Commit

Permalink
Allow lint passes to be bound by TyCtxt
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarcho committed Sep 6, 2022
1 parent a594044 commit 0126f7f
Show file tree
Hide file tree
Showing 10 changed files with 274 additions and 246 deletions.
28 changes: 19 additions & 9 deletions compiler/rustc_lint/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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>,
Expand Down Expand Up @@ -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));
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down
15 changes: 8 additions & 7 deletions compiler/rustc_lint/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!()
}
Expand All @@ -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);
}
};
Expand Down Expand Up @@ -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[..] });
Expand Down Expand Up @@ -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() {
Expand All @@ -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(
Expand Down
43 changes: 29 additions & 14 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_early_pass!($method, $passes, $constructor);
)*
)
}

macro_rules! register_late_passes {
($method:ident, [$($passes:ident: $constructor:expr,)*]) => (
$(
register_pass!($method, $passes, $constructor);
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());
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
2 changes: 1 addition & 1 deletion src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use rustc_span::source_map;
#[no_mangle]
fn __rustc_plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[&MISSING_ALLOWED_ATTR]);
reg.lint_store.register_late_pass(|| Box::new(MissingAllowedAttrPass));
reg.lint_store.register_late_pass(|_| Box::new(MissingAllowedAttrPass));
}

declare_lint! {
Expand Down
6 changes: 3 additions & 3 deletions src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ fn __rustc_plugin_registrar(reg: &mut Registry) {
&CRATE_NOT_GREY,
&CRATE_NOT_GREEN,
]);
reg.lint_store.register_late_pass(|| Box::new(PassOkay));
reg.lint_store.register_late_pass(|| Box::new(PassRedBlue));
reg.lint_store.register_late_pass(|| Box::new(PassGreyGreen));
reg.lint_store.register_late_pass(|_| Box::new(PassOkay));
reg.lint_store.register_late_pass(|_| Box::new(PassRedBlue));
reg.lint_store.register_late_pass(|_| Box::new(PassGreyGreen));
}
2 changes: 1 addition & 1 deletion src/test/ui-fulldeps/auxiliary/lint-for-crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ impl<'tcx> LateLintPass<'tcx> for Pass {
#[no_mangle]
fn __rustc_plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[&CRATE_NOT_OKAY]);
reg.lint_store.register_late_pass(|| Box::new(Pass));
reg.lint_store.register_late_pass(|_| Box::new(Pass));
}
2 changes: 1 addition & 1 deletion src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl<'tcx> LateLintPass<'tcx> for Pass {
#[no_mangle]
fn __rustc_plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[&TEST_LINT, &PLEASE_LINT]);
reg.lint_store.register_late_pass(|| Box::new(Pass));
reg.lint_store.register_late_pass(|_| Box::new(Pass));
reg.lint_store.register_group(
true,
"lint_me",
Expand Down
6 changes: 4 additions & 2 deletions src/tools/clippy/clippy_dev/src/new_lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,17 @@ fn add_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> {

let new_lint = if enable_msrv {
format!(
"store.register_{lint_pass}_pass(move || Box::new({module_name}::{camel_name}::new(msrv)));\n ",
"store.register_{lint_pass}_pass(move |{ctor_arg}| Box::new({module_name}::{camel_name}::new(msrv)));\n ",
lint_pass = lint.pass,
ctor_arg = if lint.pass == "late" { "_" } else { "" },
module_name = lint.name,
camel_name = to_camel_case(lint.name),
)
} else {
format!(
"store.register_{lint_pass}_pass(|| Box::new({module_name}::{camel_name}));\n ",
"store.register_{lint_pass}_pass(|{ctor_arg}| Box::new({module_name}::{camel_name}));\n ",
lint_pass = lint.pass,
ctor_arg = if lint.pass == "late" { "_" } else { "" },
module_name = lint.name,
camel_name = to_camel_case(lint.name),
)
Expand Down
Loading

0 comments on commit 0126f7f

Please sign in to comment.