Skip to content

Commit 319a845

Browse files
authored
Rollup merge of #101501 - Jarcho:tcx_lint_passes, r=davidtwco
Allow lint passes to be bound by `TyCtxt` This will allow storing things like `Ty<'tcx>` inside late lint passes. It's already possible to store various id types so they're already implicitly bound to a specific `TyCtxt`. r? rust-lang/compiler
2 parents 5762de5 + 0126f7f commit 319a845

File tree

10 files changed

+274
-246
lines changed

10 files changed

+274
-246
lines changed

compiler/rustc_lint/src/context.rs

+19-9
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ use std::cell::Cell;
5050
use std::iter;
5151
use std::slice;
5252

53+
type EarlyLintPassFactory = dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync;
54+
type LateLintPassFactory =
55+
dyn for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx> + sync::Send + sync::Sync;
56+
5357
/// Information about the registered lints.
5458
///
5559
/// This is basically the subset of `Context` that we can
@@ -64,11 +68,11 @@ pub struct LintStore {
6468
/// interior mutability, we don't enforce this (and lints should, in theory,
6569
/// be compatible with being constructed more than once, though not
6670
/// necessarily in a sane manner. This is safe though.)
67-
pub pre_expansion_passes: Vec<Box<dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync>>,
68-
pub early_passes: Vec<Box<dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync>>,
69-
pub late_passes: Vec<Box<dyn Fn() -> LateLintPassObject + sync::Send + sync::Sync>>,
71+
pub pre_expansion_passes: Vec<Box<EarlyLintPassFactory>>,
72+
pub early_passes: Vec<Box<EarlyLintPassFactory>>,
73+
pub late_passes: Vec<Box<LateLintPassFactory>>,
7074
/// This is unique in that we construct them per-module, so not once.
71-
pub late_module_passes: Vec<Box<dyn Fn() -> LateLintPassObject + sync::Send + sync::Sync>>,
75+
pub late_module_passes: Vec<Box<LateLintPassFactory>>,
7276

7377
/// Lints indexed by name.
7478
by_name: FxHashMap<String, TargetLint>,
@@ -186,14 +190,20 @@ impl LintStore {
186190

187191
pub fn register_late_pass(
188192
&mut self,
189-
pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync,
193+
pass: impl for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx>
194+
+ 'static
195+
+ sync::Send
196+
+ sync::Sync,
190197
) {
191198
self.late_passes.push(Box::new(pass));
192199
}
193200

194201
pub fn register_late_mod_pass(
195202
&mut self,
196-
pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync,
203+
pass: impl for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx>
204+
+ 'static
205+
+ sync::Send
206+
+ sync::Sync,
197207
) {
198208
self.late_module_passes.push(Box::new(pass));
199209
}
@@ -558,7 +568,7 @@ pub trait LintPassObject: Sized {}
558568

559569
impl LintPassObject for EarlyLintPassObject {}
560570

561-
impl LintPassObject for LateLintPassObject {}
571+
impl LintPassObject for LateLintPassObject<'_> {}
562572

563573
pub trait LintContext: Sized {
564574
type PassObject: LintPassObject;
@@ -949,8 +959,8 @@ impl<'a> EarlyContext<'a> {
949959
}
950960
}
951961

952-
impl LintContext for LateContext<'_> {
953-
type PassObject = LateLintPassObject;
962+
impl<'tcx> LintContext for LateContext<'tcx> {
963+
type PassObject = LateLintPassObject<'tcx>;
954964

955965
/// Gets the overall compiler `Session` object.
956966
fn sess(&self) -> &Session {

compiler/rustc_lint/src/late.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -306,12 +306,12 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
306306
}
307307
}
308308

309-
struct LateLintPassObjects<'a> {
310-
lints: &'a mut [LateLintPassObject],
309+
struct LateLintPassObjects<'a, 'tcx> {
310+
lints: &'a mut [LateLintPassObject<'tcx>],
311311
}
312312

313313
#[allow(rustc::lint_pass_impl_without_macro)]
314-
impl LintPass for LateLintPassObjects<'_> {
314+
impl LintPass for LateLintPassObjects<'_, '_> {
315315
fn name(&self) -> &'static str {
316316
panic!()
317317
}
@@ -329,7 +329,7 @@ macro_rules! expand_late_lint_pass_impl_methods {
329329

330330
macro_rules! late_lint_pass_impl {
331331
([], [$hir:tt], $methods:tt) => {
332-
impl<$hir> LateLintPass<$hir> for LateLintPassObjects<'_> {
332+
impl<$hir> LateLintPass<$hir> for LateLintPassObjects<'_, $hir> {
333333
expand_late_lint_pass_impl_methods!([$hir], $methods);
334334
}
335335
};
@@ -382,7 +382,7 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx>>(
382382
late_lint_mod_pass(tcx, module_def_id, builtin_lints);
383383

384384
let mut passes: Vec<_> =
385-
unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)()).collect();
385+
unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)(tcx)).collect();
386386

387387
if !passes.is_empty() {
388388
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)
418418
}
419419

420420
fn late_lint_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints: T) {
421-
let mut passes = unerased_lint_store(tcx).late_passes.iter().map(|p| (p)()).collect::<Vec<_>>();
421+
let mut passes =
422+
unerased_lint_store(tcx).late_passes.iter().map(|p| (p)(tcx)).collect::<Vec<_>>();
422423

423424
if !tcx.sess.opts.unstable_opts.no_interleave_lints {
424425
if !passes.is_empty() {
@@ -434,7 +435,7 @@ fn late_lint_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints
434435
}
435436

436437
let mut passes: Vec<_> =
437-
unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)()).collect();
438+
unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)(tcx)).collect();
438439

439440
for pass in &mut passes {
440441
tcx.sess.prof.extra_verbose_generic_activity("run_late_module_lint", pass.name()).run(

compiler/rustc_lint/src/lib.rs

+29-14
Original file line numberDiff line numberDiff line change
@@ -260,26 +260,41 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
260260
)
261261
}
262262

263-
macro_rules! register_pass {
263+
macro_rules! register_early_pass {
264264
($method:ident, $ty:ident, $constructor:expr) => {
265265
store.register_lints(&$ty::get_lints());
266266
store.$method(|| Box::new($constructor));
267267
};
268268
}
269269

270-
macro_rules! register_passes {
270+
macro_rules! register_late_pass {
271+
($method:ident, $ty:ident, $constructor:expr) => {
272+
store.register_lints(&$ty::get_lints());
273+
store.$method(|_| Box::new($constructor));
274+
};
275+
}
276+
277+
macro_rules! register_early_passes {
278+
($method:ident, [$($passes:ident: $constructor:expr,)*]) => (
279+
$(
280+
register_early_pass!($method, $passes, $constructor);
281+
)*
282+
)
283+
}
284+
285+
macro_rules! register_late_passes {
271286
($method:ident, [$($passes:ident: $constructor:expr,)*]) => (
272287
$(
273-
register_pass!($method, $passes, $constructor);
288+
register_late_pass!($method, $passes, $constructor);
274289
)*
275290
)
276291
}
277292

278293
if no_interleave_lints {
279-
pre_expansion_lint_passes!(register_passes, register_pre_expansion_pass);
280-
early_lint_passes!(register_passes, register_early_pass);
281-
late_lint_passes!(register_passes, register_late_pass);
282-
late_lint_mod_passes!(register_passes, register_late_mod_pass);
294+
pre_expansion_lint_passes!(register_early_passes, register_pre_expansion_pass);
295+
early_lint_passes!(register_early_passes, register_early_pass);
296+
late_lint_passes!(register_late_passes, register_late_pass);
297+
late_lint_mod_passes!(register_late_passes, register_late_mod_pass);
283298
} else {
284299
store.register_lints(&BuiltinCombinedPreExpansionLintPass::get_lints());
285300
store.register_lints(&BuiltinCombinedEarlyLintPass::get_lints());
@@ -510,19 +525,19 @@ fn register_internals(store: &mut LintStore) {
510525
store.register_lints(&LintPassImpl::get_lints());
511526
store.register_early_pass(|| Box::new(LintPassImpl));
512527
store.register_lints(&DefaultHashTypes::get_lints());
513-
store.register_late_pass(|| Box::new(DefaultHashTypes));
528+
store.register_late_pass(|_| Box::new(DefaultHashTypes));
514529
store.register_lints(&QueryStability::get_lints());
515-
store.register_late_pass(|| Box::new(QueryStability));
530+
store.register_late_pass(|_| Box::new(QueryStability));
516531
store.register_lints(&ExistingDocKeyword::get_lints());
517-
store.register_late_pass(|| Box::new(ExistingDocKeyword));
532+
store.register_late_pass(|_| Box::new(ExistingDocKeyword));
518533
store.register_lints(&TyTyKind::get_lints());
519-
store.register_late_pass(|| Box::new(TyTyKind));
534+
store.register_late_pass(|_| Box::new(TyTyKind));
520535
store.register_lints(&Diagnostics::get_lints());
521-
store.register_late_pass(|| Box::new(Diagnostics));
536+
store.register_late_pass(|_| Box::new(Diagnostics));
522537
store.register_lints(&BadOptAccess::get_lints());
523-
store.register_late_pass(|| Box::new(BadOptAccess));
538+
store.register_late_pass(|_| Box::new(BadOptAccess));
524539
store.register_lints(&PassByValue::get_lints());
525-
store.register_late_pass(|| Box::new(PassByValue));
540+
store.register_late_pass(|_| Box::new(PassByValue));
526541
// FIXME(davidtwco): deliberately do not include `UNTRANSLATABLE_DIAGNOSTIC` and
527542
// `DIAGNOSTIC_OUTSIDE_OF_IMPL` here because `-Wrustc::internal` is provided to every crate and
528543
// these lints will trigger all of the time - change this once migration to diagnostic structs

compiler/rustc_lint/src/passes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -244,4 +244,4 @@ macro_rules! declare_combined_early_lint_pass {
244244

245245
/// A lint pass boxed up as a trait object.
246246
pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + 'static>;
247-
pub type LateLintPassObject = Box<dyn for<'tcx> LateLintPass<'tcx> + sync::Send + 'static>;
247+
pub type LateLintPassObject<'tcx> = Box<dyn LateLintPass<'tcx> + sync::Send + 'tcx>;

src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rustc_span::source_map;
2121
#[no_mangle]
2222
fn __rustc_plugin_registrar(reg: &mut Registry) {
2323
reg.lint_store.register_lints(&[&MISSING_ALLOWED_ATTR]);
24-
reg.lint_store.register_late_pass(|| Box::new(MissingAllowedAttrPass));
24+
reg.lint_store.register_late_pass(|_| Box::new(MissingAllowedAttrPass));
2525
}
2626

2727
declare_lint! {

src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ fn __rustc_plugin_registrar(reg: &mut Registry) {
7474
&CRATE_NOT_GREY,
7575
&CRATE_NOT_GREEN,
7676
]);
77-
reg.lint_store.register_late_pass(|| Box::new(PassOkay));
78-
reg.lint_store.register_late_pass(|| Box::new(PassRedBlue));
79-
reg.lint_store.register_late_pass(|| Box::new(PassGreyGreen));
77+
reg.lint_store.register_late_pass(|_| Box::new(PassOkay));
78+
reg.lint_store.register_late_pass(|_| Box::new(PassRedBlue));
79+
reg.lint_store.register_late_pass(|_| Box::new(PassGreyGreen));
8080
}

src/test/ui-fulldeps/auxiliary/lint-for-crate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,5 @@ impl<'tcx> LateLintPass<'tcx> for Pass {
3939
#[no_mangle]
4040
fn __rustc_plugin_registrar(reg: &mut Registry) {
4141
reg.lint_store.register_lints(&[&CRATE_NOT_OKAY]);
42-
reg.lint_store.register_late_pass(|| Box::new(Pass));
42+
reg.lint_store.register_late_pass(|_| Box::new(Pass));
4343
}

src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ impl<'tcx> LateLintPass<'tcx> for Pass {
3636
#[no_mangle]
3737
fn __rustc_plugin_registrar(reg: &mut Registry) {
3838
reg.lint_store.register_lints(&[&TEST_LINT, &PLEASE_LINT]);
39-
reg.lint_store.register_late_pass(|| Box::new(Pass));
39+
reg.lint_store.register_late_pass(|_| Box::new(Pass));
4040
reg.lint_store.register_group(
4141
true,
4242
"lint_me",

src/tools/clippy/clippy_dev/src/new_lint.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,17 @@ fn add_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> {
120120

121121
let new_lint = if enable_msrv {
122122
format!(
123-
"store.register_{lint_pass}_pass(move || Box::new({module_name}::{camel_name}::new(msrv)));\n ",
123+
"store.register_{lint_pass}_pass(move |{ctor_arg}| Box::new({module_name}::{camel_name}::new(msrv)));\n ",
124124
lint_pass = lint.pass,
125+
ctor_arg = if lint.pass == "late" { "_" } else { "" },
125126
module_name = lint.name,
126127
camel_name = to_camel_case(lint.name),
127128
)
128129
} else {
129130
format!(
130-
"store.register_{lint_pass}_pass(|| Box::new({module_name}::{camel_name}));\n ",
131+
"store.register_{lint_pass}_pass(|{ctor_arg}| Box::new({module_name}::{camel_name}));\n ",
131132
lint_pass = lint.pass,
133+
ctor_arg = if lint.pass == "late" { "_" } else { "" },
132134
module_name = lint.name,
133135
camel_name = to_camel_case(lint.name),
134136
)

0 commit comments

Comments
 (0)