Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce macro usage for lints #104863

Merged
merged 9 commits into from
Dec 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions compiler/rustc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,8 @@ fn run_compiler(
interface::run_compiler(config, |compiler| {
let sopts = &compiler.session().opts;
if sopts.describe_lints {
let mut lint_store = rustc_lint::new_lint_store(
sopts.unstable_opts.no_interleave_lints,
compiler.session().enable_internal_lints(),
);
let mut lint_store =
rustc_lint::new_lint_store(compiler.session().enable_internal_lints());
let registered_lints =
if let Some(register_lints) = compiler.register_lints() {
register_lints(compiler.session(), &mut lint_store);
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,7 @@ pub fn register_plugins<'a>(
});
}

let mut lint_store = rustc_lint::new_lint_store(
sess.opts.unstable_opts.no_interleave_lints,
sess.enable_internal_lints(),
);
let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
register_lints(sess, &mut lint_store);

let registrars =
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,6 @@ fn test_unstable_options_tracking_hash() {
untracked!(mir_pretty_relative_line_numbers, true);
untracked!(nll_facts, true);
untracked!(no_analysis, true);
untracked!(no_interleave_lints, true);
untracked!(no_leak_check, true);
untracked!(no_parallel_llvm, true);
untracked!(parse_only, true);
Expand Down
93 changes: 17 additions & 76 deletions compiler/rustc_lint/src/early.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ use rustc_session::Session;
use rustc_span::symbol::Ident;
use rustc_span::Span;

use std::slice;

macro_rules! run_early_pass { ($cx:expr, $f:ident, $($args:expr),*) => ({
$cx.pass.$f(&$cx.context, $($args),*);
}) }
Expand Down Expand Up @@ -300,20 +298,14 @@ impl LintPass for EarlyLintPassObjects<'_> {
}
}

macro_rules! expand_early_lint_pass_impl_methods {
([$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
$(fn $name(&mut self, context: &EarlyContext<'_>, $($param: $arg),*) {
for obj in self.lints.iter_mut() {
obj.$name(context, $($param),*);
}
})*
)
}

macro_rules! early_lint_pass_impl {
([], [$($methods:tt)*]) => (
([], [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
impl EarlyLintPass for EarlyLintPassObjects<'_> {
expand_early_lint_pass_impl_methods!([$($methods)*]);
$(fn $name(&mut self, context: &EarlyContext<'_>, $($param: $arg),*) {
for obj in self.lints.iter_mut() {
obj.$name(context, $($param),*);
}
})*
}
)
}
Expand Down Expand Up @@ -371,87 +363,36 @@ impl<'a> EarlyCheckNode<'a> for (ast::NodeId, &'a [ast::Attribute], &'a [P<ast::
}
}

fn early_lint_node<'a>(
sess: &Session,
warn_about_weird_lints: bool,
lint_store: &LintStore,
registered_tools: &RegisteredTools,
buffered: LintBuffer,
pass: impl EarlyLintPass,
check_node: impl EarlyCheckNode<'a>,
) -> LintBuffer {
let mut cx = EarlyContextAndPass {
context: EarlyContext::new(
sess,
warn_about_weird_lints,
lint_store,
registered_tools,
buffered,
),
pass,
};

cx.with_lint_attrs(check_node.id(), check_node.attrs(), |cx| check_node.check(cx));
cx.context.buffered
}

pub fn check_ast_node<'a>(
sess: &Session,
pre_expansion: bool,
lint_store: &LintStore,
registered_tools: &RegisteredTools,
lint_buffer: Option<LintBuffer>,
builtin_lints: impl EarlyLintPass,
builtin_lints: impl EarlyLintPass + 'static,
check_node: impl EarlyCheckNode<'a>,
) {
let passes =
if pre_expansion { &lint_store.pre_expansion_passes } else { &lint_store.early_passes };
let mut passes: Vec<_> = passes.iter().map(|p| (p)()).collect();
let mut buffered = lint_buffer.unwrap_or_default();

if sess.opts.unstable_opts.no_interleave_lints {
for (i, pass) in passes.iter_mut().enumerate() {
buffered =
sess.prof.verbose_generic_activity_with_arg("run_lint", pass.name()).run(|| {
early_lint_node(
sess,
!pre_expansion && i == 0,
lint_store,
registered_tools,
buffered,
EarlyLintPassObjects { lints: slice::from_mut(pass) },
check_node,
)
});
}
} else {
buffered = early_lint_node(
passes.push(Box::new(builtin_lints));

let mut cx = EarlyContextAndPass {
context: EarlyContext::new(
sess,
!pre_expansion,
lint_store,
registered_tools,
buffered,
builtin_lints,
check_node,
);

if !passes.is_empty() {
buffered = early_lint_node(
sess,
false,
lint_store,
registered_tools,
buffered,
EarlyLintPassObjects { lints: &mut passes[..] },
check_node,
);
}
}
lint_buffer.unwrap_or_default(),
),
pass: EarlyLintPassObjects { lints: &mut passes[..] },
};
cx.with_lint_attrs(check_node.id(), check_node.attrs(), |cx| check_node.check(cx));

// All of the buffered lints should have been emitted at this point.
// If not, that means that we somehow buffered a lint for a node id
// that was not lint-checked (perhaps it doesn't exist?). This is a bug.
for (id, lints) in buffered.map {
for (id, lints) in cx.context.buffered.map {
for early_lint in lints {
sess.delay_span_bug(
early_lint.span,
Expand Down
100 changes: 23 additions & 77 deletions compiler/rustc_lint/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ 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.
Expand Down Expand Up @@ -313,45 +312,42 @@ impl LintPass for LateLintPassObjects<'_, '_> {
}
}

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) => {
([], [$hir:tt], [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => {
impl<$hir> LateLintPass<$hir> for LateLintPassObjects<'_, $hir> {
expand_late_lint_pass_impl_methods!([$hir], $methods);
$(fn $name(&mut self, context: &LateContext<$hir>, $($param: $arg),*) {
for obj in self.lints.iter_mut() {
obj.$name(context, $($param),*);
}
})*
}
};
}

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 passes: Vec<_> =
unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)(tcx)).collect();
passes.push(Box::new(builtin_lints));
let pass = LateLintPassObjects { lints: &mut passes[..] };

let mut cx = LateContextAndPass { context, pass };

let (module, _span, hir_id) = tcx.hir().get_module(module_def_id);
Expand All @@ -365,46 +361,29 @@ 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 passes =
unerased_lint_store(tcx).late_passes.iter().map(|p| (p)(tcx)).collect::<Vec<_>>();
passes.push(Box::new(builtin_lints));
let pass = LateLintPassObjects { lints: &mut passes[..] };

let mut cx = LateContextAndPass { context, pass };

// 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);
Expand All @@ -413,41 +392,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,
) {
Expand Down
Loading