Skip to content

Commit 4ff5a36

Browse files
committed
Speed up the "builtin lints only" case.
This commit partly undoes #104863, which combined the builtin lints pass with other lints. This caused a slowdown, because often there are no other lints, and it's faster to do a pass with a single lint directly than it is to do a combined pass with a `passes` vector containing a single lint.
1 parent 3c53781 commit 4ff5a36

File tree

2 files changed

+51
-7
lines changed

2 files changed

+51
-7
lines changed

compiler/rustc_lint/src/early.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -393,12 +393,27 @@ pub fn check_ast_node<'a>(
393393
lint_buffer.unwrap_or_default(),
394394
);
395395

396+
// Note: `passes` is often empty. In that case, it's faster to run
397+
// `builtin_lints` directly rather than bundling it up into the
398+
// `RuntimeCombinedEarlyLintPass`.
396399
let passes =
397400
if pre_expansion { &lint_store.pre_expansion_passes } else { &lint_store.early_passes };
398-
let mut passes: Vec<EarlyLintPassObject> = passes.iter().map(|mk_pass| (mk_pass)()).collect();
399-
passes.push(Box::new(builtin_lints));
400-
let pass = RuntimeCombinedEarlyLintPass { passes: &mut passes[..] };
401+
if passes.is_empty() {
402+
check_ast_node_inner(sess, check_node, context, builtin_lints);
403+
} else {
404+
let mut passes: Vec<_> = passes.iter().map(|mk_pass| (mk_pass)()).collect();
405+
passes.push(Box::new(builtin_lints));
406+
let pass = RuntimeCombinedEarlyLintPass { passes: &mut passes[..] };
407+
check_ast_node_inner(sess, check_node, context, pass);
408+
}
409+
}
401410

411+
pub fn check_ast_node_inner<'a, T: EarlyLintPass>(
412+
sess: &Session,
413+
check_node: impl EarlyCheckNode<'a>,
414+
context: EarlyContext<'_>,
415+
pass: T,
416+
) {
402417
let mut cx = EarlyContextAndPass { context, pass };
403418

404419
cx.with_lint_attrs(check_node.id(), check_node.attrs(), |cx| check_node.check(cx));

compiler/rustc_lint/src/late.rs

+33-4
Original file line numberDiff line numberDiff line change
@@ -349,11 +349,26 @@ pub(super) fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>(
349349
only_module: true,
350350
};
351351

352+
// Note: `passes` is often empty. In that case, it's faster to run
353+
// `builtin_lints` directly rather than bundling it up into the
354+
// `RuntimeCombinedLateLintPass`.
352355
let mut passes: Vec<_> =
353356
unerased_lint_store(tcx).late_module_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect();
354-
passes.push(Box::new(builtin_lints));
355-
let pass = RuntimeCombinedLateLintPass { passes: &mut passes[..] };
357+
if passes.is_empty() {
358+
late_lint_mod_inner(tcx, module_def_id, context, builtin_lints);
359+
} else {
360+
passes.push(Box::new(builtin_lints));
361+
let pass = RuntimeCombinedLateLintPass { passes: &mut passes[..] };
362+
late_lint_mod_inner(tcx, module_def_id, context, pass);
363+
}
364+
}
356365

366+
fn late_lint_mod_inner<'tcx, T: LateLintPass<'tcx>>(
367+
tcx: TyCtxt<'tcx>,
368+
module_def_id: LocalDefId,
369+
context: LateContext<'tcx>,
370+
pass: T,
371+
) {
357372
let mut cx = LateContextAndPass { context, pass };
358373

359374
let (module, _span, hir_id) = tcx.hir().get_module(module_def_id);
@@ -380,11 +395,25 @@ fn late_lint_crate<'tcx, T: LateLintPass<'tcx> + 'tcx>(tcx: TyCtxt<'tcx>, builti
380395
only_module: false,
381396
};
382397

398+
// Note: `passes` is often empty. In that case, it's faster to run
399+
// `builtin_lints` directly rather than bundling it up into the
400+
// `RuntimeCombinedLateLintPass`.
383401
let mut passes: Vec<_> =
384402
unerased_lint_store(tcx).late_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect();
385-
passes.push(Box::new(builtin_lints));
386-
let pass = RuntimeCombinedLateLintPass { passes: &mut passes[..] };
403+
if passes.is_empty() {
404+
late_lint_crate_inner(tcx, context, builtin_lints);
405+
} else {
406+
passes.push(Box::new(builtin_lints));
407+
let pass = RuntimeCombinedLateLintPass { passes: &mut passes[..] };
408+
late_lint_crate_inner(tcx, context, pass);
409+
}
410+
}
387411

412+
fn late_lint_crate_inner<'tcx, T: LateLintPass<'tcx>>(
413+
tcx: TyCtxt<'tcx>,
414+
context: LateContext<'tcx>,
415+
pass: T,
416+
) {
388417
let mut cx = LateContextAndPass { context, pass };
389418

390419
// Visit the whole crate.

0 commit comments

Comments
 (0)