use rustc_session::lint::LintPass;
use rustc_session::lint::builtin::HardwiredLints;
use crate::context::{EarlyContext, LateContext};
#[macro_export]
macro_rules! late_lint_methods {
($macro:path, $args:tt) => (
$macro!($args, [
fn check_body(a: &rustc_hir::Body<'tcx>);
fn check_body_post(a: &rustc_hir::Body<'tcx>);
fn check_crate();
fn check_crate_post();
fn check_mod(a: &'tcx rustc_hir::Mod<'tcx>, b: rustc_hir::HirId);
fn check_foreign_item(a: &'tcx rustc_hir::ForeignItem<'tcx>);
fn check_item(a: &'tcx rustc_hir::Item<'tcx>);
fn check_item_post(a: &'tcx rustc_hir::Item<'tcx>);
fn check_local(a: &'tcx rustc_hir::LetStmt<'tcx>);
fn check_block(a: &'tcx rustc_hir::Block<'tcx>);
fn check_block_post(a: &'tcx rustc_hir::Block<'tcx>);
fn check_stmt(a: &'tcx rustc_hir::Stmt<'tcx>);
fn check_arm(a: &'tcx rustc_hir::Arm<'tcx>);
fn check_pat(a: &'tcx rustc_hir::Pat<'tcx>);
fn check_expr(a: &'tcx rustc_hir::Expr<'tcx>);
fn check_expr_post(a: &'tcx rustc_hir::Expr<'tcx>);
fn check_ty(a: &'tcx rustc_hir::Ty<'tcx>);
fn check_generic_param(a: &'tcx rustc_hir::GenericParam<'tcx>);
fn check_generics(a: &'tcx rustc_hir::Generics<'tcx>);
fn check_poly_trait_ref(a: &'tcx rustc_hir::PolyTraitRef<'tcx>);
fn check_fn(
a: rustc_hir::intravisit::FnKind<'tcx>,
b: &'tcx rustc_hir::FnDecl<'tcx>,
c: &'tcx rustc_hir::Body<'tcx>,
d: rustc_span::Span,
e: rustc_span::def_id::LocalDefId);
fn check_trait_item(a: &'tcx rustc_hir::TraitItem<'tcx>);
fn check_impl_item(a: &'tcx rustc_hir::ImplItem<'tcx>);
fn check_impl_item_post(a: &'tcx rustc_hir::ImplItem<'tcx>);
fn check_struct_def(a: &'tcx rustc_hir::VariantData<'tcx>);
fn check_field_def(a: &'tcx rustc_hir::FieldDef<'tcx>);
fn check_variant(a: &'tcx rustc_hir::Variant<'tcx>);
fn check_path(a: &rustc_hir::Path<'tcx>, b: rustc_hir::HirId);
fn check_attribute(a: &'tcx rustc_ast::Attribute);
fn check_attributes(a: &'tcx [rustc_ast::Attribute]);
fn check_attributes_post(a: &'tcx [rustc_ast::Attribute]);
]);
)
}
macro_rules! declare_late_lint_pass {
([], [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
pub trait LateLintPass<'tcx>: LintPass {
$(#[inline(always)] fn $name(&mut self, _: &LateContext<'tcx>, $(_: $arg),*) {})*
}
)
}
late_lint_methods!(declare_late_lint_pass, []);
impl LateLintPass<'_> for HardwiredLints {}
#[macro_export]
macro_rules! expand_combined_late_lint_pass_method {
([$($pass:ident),*], $self: ident, $name: ident, $params:tt) => ({
$($self.$pass.$name $params;)*
})
}
#[macro_export]
macro_rules! expand_combined_late_lint_pass_methods {
($passes:tt, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
$(fn $name(&mut self, context: &$crate::LateContext<'tcx>, $($param: $arg),*) {
$crate::expand_combined_late_lint_pass_method!($passes, self, $name, (context, $($param),*));
})*
)
}
#[macro_export]
macro_rules! declare_combined_late_lint_pass {
([$v:vis $name:ident, [$($pass:ident: $constructor:expr,)*]], $methods:tt) => (
#[allow(non_snake_case)]
$v struct $name {
$($pass: $pass,)*
}
impl $name {
$v fn new() -> Self {
Self {
$($pass: $constructor,)*
}
}
$v fn get_lints() -> $crate::LintVec {
let mut lints = Vec::new();
$(lints.extend_from_slice(&$pass::get_lints());)*
lints
}
}
impl<'tcx> $crate::LateLintPass<'tcx> for $name {
$crate::expand_combined_late_lint_pass_methods!([$($pass),*], $methods);
}
#[allow(rustc::lint_pass_impl_without_macro)]
impl $crate::LintPass for $name {
fn name(&self) -> &'static str {
panic!()
}
}
)
}
#[macro_export]
macro_rules! early_lint_methods {
($macro:path, $args:tt) => (
$macro!($args, [
fn check_param(a: &rustc_ast::Param);
fn check_ident(a: rustc_span::symbol::Ident);
fn check_crate(a: &rustc_ast::Crate);
fn check_crate_post(a: &rustc_ast::Crate);
fn check_item(a: &rustc_ast::Item);
fn check_item_post(a: &rustc_ast::Item);
fn check_local(a: &rustc_ast::Local);
fn check_block(a: &rustc_ast::Block);
fn check_stmt(a: &rustc_ast::Stmt);
fn check_arm(a: &rustc_ast::Arm);
fn check_pat(a: &rustc_ast::Pat);
fn check_pat_post(a: &rustc_ast::Pat);
fn check_expr(a: &rustc_ast::Expr);
fn check_expr_post(a: &rustc_ast::Expr);
fn check_ty(a: &rustc_ast::Ty);
fn check_generic_arg(a: &rustc_ast::GenericArg);
fn check_generic_param(a: &rustc_ast::GenericParam);
fn check_generics(a: &rustc_ast::Generics);
fn check_poly_trait_ref(a: &rustc_ast::PolyTraitRef);
fn check_fn(
a: rustc_ast::visit::FnKind<'_>,
c: rustc_span::Span,
d_: rustc_ast::NodeId);
fn check_trait_item(a: &rustc_ast::AssocItem);
fn check_impl_item(a: &rustc_ast::AssocItem);
fn check_variant(a: &rustc_ast::Variant);
fn check_attribute(a: &rustc_ast::Attribute);
fn check_attributes(a: &[rustc_ast::Attribute]);
fn check_attributes_post(a: &[rustc_ast::Attribute]);
fn check_mac_def(a: &rustc_ast::MacroDef);
fn check_mac(a: &rustc_ast::MacCall);
fn enter_where_predicate(a: &rustc_ast::WherePredicate);
fn exit_where_predicate(a: &rustc_ast::WherePredicate);
]);
)
}
macro_rules! declare_early_lint_pass {
([], [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
pub trait EarlyLintPass: LintPass {
$(#[inline(always)] fn $name(&mut self, _: &EarlyContext<'_>, $(_: $arg),*) {})*
}
)
}
early_lint_methods!(declare_early_lint_pass, []);
#[macro_export]
macro_rules! expand_combined_early_lint_pass_method {
([$($pass:ident),*], $self: ident, $name: ident, $params:tt) => ({
$($self.$pass.$name $params;)*
})
}
#[macro_export]
macro_rules! expand_combined_early_lint_pass_methods {
($passes:tt, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
$(fn $name(&mut self, context: &$crate::EarlyContext<'_>, $($param: $arg),*) {
$crate::expand_combined_early_lint_pass_method!($passes, self, $name, (context, $($param),*));
})*
)
}
#[macro_export]
macro_rules! declare_combined_early_lint_pass {
([$v:vis $name:ident, [$($pass:ident: $constructor:expr,)*]], $methods:tt) => (
#[allow(non_snake_case)]
$v struct $name {
$($pass: $pass,)*
}
impl $name {
$v fn new() -> Self {
Self {
$($pass: $constructor,)*
}
}
$v fn get_lints() -> $crate::LintVec {
let mut lints = Vec::new();
$(lints.extend_from_slice(&$pass::get_lints());)*
lints
}
}
impl $crate::EarlyLintPass for $name {
$crate::expand_combined_early_lint_pass_methods!([$($pass),*], $methods);
}
#[allow(rustc::lint_pass_impl_without_macro)]
impl $crate::LintPass for $name {
fn name(&self) -> &'static str {
panic!()
}
}
)
}
pub(crate) type EarlyLintPassObject = Box<dyn EarlyLintPass + 'static>;
pub(crate) type LateLintPassObject<'tcx> = Box<dyn LateLintPass<'tcx> + 'tcx>;