2020-01-09 00:52:01 -06:00
|
|
|
use crate::context::{EarlyContext, LateContext};
|
2014-11-06 02:05:53 -06:00
|
|
|
|
2020-04-27 12:56:11 -05:00
|
|
|
use rustc_ast as ast;
|
2020-01-07 11:12:06 -06:00
|
|
|
use rustc_data_structures::sync;
|
2020-01-04 19:37:57 -06:00
|
|
|
use rustc_hir as hir;
|
2020-01-05 03:47:20 -06:00
|
|
|
use rustc_session::lint::builtin::HardwiredLints;
|
2020-01-09 00:52:01 -06:00
|
|
|
use rustc_session::lint::LintPass;
|
2020-04-19 06:00:18 -05:00
|
|
|
use rustc_span::symbol::{Ident, Symbol};
|
2019-12-31 11:15:40 -06:00
|
|
|
use rustc_span::Span;
|
2014-06-06 17:49:48 -05:00
|
|
|
|
2018-06-21 02:04:50 -05:00
|
|
|
#[macro_export]
|
|
|
|
macro_rules! late_lint_methods {
|
|
|
|
($macro:path, $args:tt, [$hir:tt]) => (
|
|
|
|
$macro!($args, [$hir], [
|
2019-11-29 06:43:03 -06:00
|
|
|
fn check_param(a: &$hir hir::Param<$hir>);
|
2019-11-29 04:09:23 -06:00
|
|
|
fn check_body(a: &$hir hir::Body<$hir>);
|
|
|
|
fn check_body_post(a: &$hir hir::Body<$hir>);
|
2020-04-19 06:00:18 -05:00
|
|
|
fn check_name(a: Span, b: Symbol);
|
2019-11-28 04:49:29 -06:00
|
|
|
fn check_crate(a: &$hir hir::Crate<$hir>);
|
|
|
|
fn check_crate_post(a: &$hir hir::Crate<$hir>);
|
2019-11-29 03:24:47 -06:00
|
|
|
fn check_mod(a: &$hir hir::Mod<$hir>, b: Span, c: hir::HirId);
|
|
|
|
fn check_mod_post(a: &$hir hir::Mod<$hir>, b: Span, c: hir::HirId);
|
2019-11-28 13:18:29 -06:00
|
|
|
fn check_foreign_item(a: &$hir hir::ForeignItem<$hir>);
|
|
|
|
fn check_foreign_item_post(a: &$hir hir::ForeignItem<$hir>);
|
2019-11-28 12:28:50 -06:00
|
|
|
fn check_item(a: &$hir hir::Item<$hir>);
|
|
|
|
fn check_item_post(a: &$hir hir::Item<$hir>);
|
2019-11-29 06:43:03 -06:00
|
|
|
fn check_local(a: &$hir hir::Local<$hir>);
|
|
|
|
fn check_block(a: &$hir hir::Block<$hir>);
|
|
|
|
fn check_block_post(a: &$hir hir::Block<$hir>);
|
|
|
|
fn check_stmt(a: &$hir hir::Stmt<$hir>);
|
|
|
|
fn check_arm(a: &$hir hir::Arm<$hir>);
|
|
|
|
fn check_pat(a: &$hir hir::Pat<$hir>);
|
|
|
|
fn check_expr(a: &$hir hir::Expr<$hir>);
|
|
|
|
fn check_expr_post(a: &$hir hir::Expr<$hir>);
|
2019-11-30 10:46:46 -06:00
|
|
|
fn check_ty(a: &$hir hir::Ty<$hir>);
|
2020-10-09 17:20:06 -05:00
|
|
|
fn check_generic_arg(a: &$hir hir::GenericArg<$hir>);
|
2019-11-30 10:46:46 -06:00
|
|
|
fn check_generic_param(a: &$hir hir::GenericParam<$hir>);
|
|
|
|
fn check_generics(a: &$hir hir::Generics<$hir>);
|
|
|
|
fn check_where_predicate(a: &$hir hir::WherePredicate<$hir>);
|
|
|
|
fn check_poly_trait_ref(a: &$hir hir::PolyTraitRef<$hir>, b: hir::TraitBoundModifier);
|
2018-06-21 02:04:50 -05:00
|
|
|
fn check_fn(
|
2020-01-07 11:12:06 -06:00
|
|
|
a: rustc_hir::intravisit::FnKind<$hir>,
|
2019-11-30 10:46:46 -06:00
|
|
|
b: &$hir hir::FnDecl<$hir>,
|
2019-11-29 04:09:23 -06:00
|
|
|
c: &$hir hir::Body<$hir>,
|
2018-06-21 02:04:50 -05:00
|
|
|
d: Span,
|
2019-02-06 07:16:11 -06:00
|
|
|
e: hir::HirId);
|
2018-06-21 02:04:50 -05:00
|
|
|
fn check_fn_post(
|
2020-01-07 11:12:06 -06:00
|
|
|
a: rustc_hir::intravisit::FnKind<$hir>,
|
2019-11-30 10:46:46 -06:00
|
|
|
b: &$hir hir::FnDecl<$hir>,
|
2019-11-29 04:09:23 -06:00
|
|
|
c: &$hir hir::Body<$hir>,
|
2018-06-21 02:04:50 -05:00
|
|
|
d: Span,
|
2019-02-06 07:16:11 -06:00
|
|
|
e: hir::HirId
|
2018-06-21 02:04:50 -05:00
|
|
|
);
|
2019-11-28 14:47:10 -06:00
|
|
|
fn check_trait_item(a: &$hir hir::TraitItem<$hir>);
|
|
|
|
fn check_trait_item_post(a: &$hir hir::TraitItem<$hir>);
|
2019-11-28 15:16:44 -06:00
|
|
|
fn check_impl_item(a: &$hir hir::ImplItem<$hir>);
|
|
|
|
fn check_impl_item_post(a: &$hir hir::ImplItem<$hir>);
|
2019-11-29 02:26:18 -06:00
|
|
|
fn check_struct_def(a: &$hir hir::VariantData<$hir>);
|
|
|
|
fn check_struct_def_post(a: &$hir hir::VariantData<$hir>);
|
2019-11-29 02:40:33 -06:00
|
|
|
fn check_struct_field(a: &$hir hir::StructField<$hir>);
|
2019-11-29 02:26:18 -06:00
|
|
|
fn check_variant(a: &$hir hir::Variant<$hir>);
|
|
|
|
fn check_variant_post(a: &$hir hir::Variant<$hir>);
|
2018-06-21 02:04:50 -05:00
|
|
|
fn check_lifetime(a: &$hir hir::Lifetime);
|
2019-11-30 10:46:46 -06:00
|
|
|
fn check_path(a: &$hir hir::Path<$hir>, b: hir::HirId);
|
2018-06-21 02:04:50 -05:00
|
|
|
fn check_attribute(a: &$hir ast::Attribute);
|
|
|
|
|
|
|
|
/// Called when entering a syntax node that can have lint attributes such
|
|
|
|
/// as `#[allow(...)]`. Called with *all* the attributes of that node.
|
|
|
|
fn enter_lint_attrs(a: &$hir [ast::Attribute]);
|
|
|
|
|
|
|
|
/// Counterpart to `enter_lint_attrs`.
|
|
|
|
fn exit_lint_attrs(a: &$hir [ast::Attribute]);
|
|
|
|
]);
|
|
|
|
)
|
|
|
|
}
|
2015-09-14 18:35:25 -05:00
|
|
|
|
|
|
|
/// Trait for types providing lint checks.
|
|
|
|
///
|
|
|
|
/// Each `check` method checks a single syntax node, and should not
|
|
|
|
/// invoke methods recursively (unlike `Visitor`). By default they
|
|
|
|
/// do nothing.
|
|
|
|
//
|
|
|
|
// FIXME: eliminate the duplication with `Visitor`. But this also
|
|
|
|
// contains a few lint-specific methods with no equivalent in `Visitor`.
|
2018-06-21 02:04:50 -05:00
|
|
|
|
|
|
|
macro_rules! expand_lint_pass_methods {
|
|
|
|
($context:ty, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
|
2018-08-11 12:28:35 -05:00
|
|
|
$(#[inline(always)] fn $name(&mut self, _: $context, $(_: $arg),*) {})*
|
2018-06-21 02:04:50 -05:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! declare_late_lint_pass {
|
|
|
|
([], [$hir:tt], [$($methods:tt)*]) => (
|
2020-06-25 15:41:36 -05:00
|
|
|
pub trait LateLintPass<$hir>: LintPass {
|
|
|
|
expand_lint_pass_methods!(&LateContext<$hir>, [$($methods)*]);
|
2018-06-21 02:04:50 -05:00
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
late_lint_methods!(declare_late_lint_pass, [], ['tcx]);
|
|
|
|
|
2020-06-25 15:41:36 -05:00
|
|
|
impl LateLintPass<'_> for HardwiredLints {}
|
2020-01-05 03:07:26 -06:00
|
|
|
|
2018-06-21 02:04:50 -05:00
|
|
|
#[macro_export]
|
|
|
|
macro_rules! expand_combined_late_lint_pass_method {
|
|
|
|
([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({
|
|
|
|
$($self.$passes.$name $params;)*
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! expand_combined_late_lint_pass_methods {
|
|
|
|
($passes:tt, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
|
2020-06-25 15:41:36 -05:00
|
|
|
$(fn $name(&mut self, context: &LateContext<'tcx>, $($param: $arg),*) {
|
2018-06-21 02:04:50 -05:00
|
|
|
expand_combined_late_lint_pass_method!($passes, self, $name, (context, $($param),*));
|
|
|
|
})*
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! declare_combined_late_lint_pass {
|
2019-01-30 18:36:11 -06:00
|
|
|
([$v:vis $name:ident, [$($passes:ident: $constructor:expr,)*]], [$hir:tt], $methods:tt) => (
|
2018-06-21 02:04:50 -05:00
|
|
|
#[allow(non_snake_case)]
|
2019-01-30 18:36:11 -06:00
|
|
|
$v struct $name {
|
2018-06-21 02:04:50 -05:00
|
|
|
$($passes: $passes,)*
|
|
|
|
}
|
|
|
|
|
|
|
|
impl $name {
|
2019-01-30 18:36:11 -06:00
|
|
|
$v fn new() -> Self {
|
2018-06-21 02:04:50 -05:00
|
|
|
Self {
|
|
|
|
$($passes: $constructor,)*
|
|
|
|
}
|
|
|
|
}
|
2019-10-07 17:04:05 -05:00
|
|
|
|
|
|
|
$v fn get_lints() -> LintArray {
|
|
|
|
let mut lints = Vec::new();
|
|
|
|
$(lints.extend_from_slice(&$passes::get_lints());)*
|
|
|
|
lints
|
|
|
|
}
|
2018-06-21 02:04:50 -05:00
|
|
|
}
|
|
|
|
|
2020-06-25 15:41:36 -05:00
|
|
|
impl<'tcx> LateLintPass<'tcx> for $name {
|
2018-06-21 02:04:50 -05:00
|
|
|
expand_combined_late_lint_pass_methods!([$($passes),*], $methods);
|
|
|
|
}
|
|
|
|
|
2020-01-09 00:52:01 -06:00
|
|
|
#[allow(rustc::lint_pass_impl_without_macro)]
|
2018-06-21 02:04:50 -05:00
|
|
|
impl LintPass for $name {
|
2019-01-18 00:40:55 -06:00
|
|
|
fn name(&self) -> &'static str {
|
|
|
|
panic!()
|
|
|
|
}
|
2018-06-21 02:04:50 -05:00
|
|
|
}
|
|
|
|
)
|
2015-09-14 18:35:25 -05:00
|
|
|
}
|
|
|
|
|
2019-01-18 00:40:55 -06:00
|
|
|
#[macro_export]
|
|
|
|
macro_rules! early_lint_methods {
|
|
|
|
($macro:path, $args:tt) => (
|
|
|
|
$macro!($args, [
|
2019-08-27 06:24:32 -05:00
|
|
|
fn check_param(a: &ast::Param);
|
2020-04-19 06:00:18 -05:00
|
|
|
fn check_ident(a: Ident);
|
2019-01-18 00:40:55 -06:00
|
|
|
fn check_crate(a: &ast::Crate);
|
|
|
|
fn check_crate_post(a: &ast::Crate);
|
|
|
|
fn check_mod(a: &ast::Mod, b: Span, c: ast::NodeId);
|
|
|
|
fn check_mod_post(a: &ast::Mod, b: Span, c: ast::NodeId);
|
|
|
|
fn check_foreign_item(a: &ast::ForeignItem);
|
|
|
|
fn check_foreign_item_post(a: &ast::ForeignItem);
|
|
|
|
fn check_item(a: &ast::Item);
|
|
|
|
fn check_item_post(a: &ast::Item);
|
|
|
|
fn check_local(a: &ast::Local);
|
|
|
|
fn check_block(a: &ast::Block);
|
|
|
|
fn check_block_post(a: &ast::Block);
|
|
|
|
fn check_stmt(a: &ast::Stmt);
|
|
|
|
fn check_arm(a: &ast::Arm);
|
2019-04-21 09:09:30 -05:00
|
|
|
fn check_pat(a: &ast::Pat);
|
2020-03-27 15:53:07 -05:00
|
|
|
fn check_anon_const(a: &ast::AnonConst);
|
2019-04-21 09:09:30 -05:00
|
|
|
fn check_pat_post(a: &ast::Pat);
|
2019-01-18 00:40:55 -06:00
|
|
|
fn check_expr(a: &ast::Expr);
|
|
|
|
fn check_expr_post(a: &ast::Expr);
|
|
|
|
fn check_ty(a: &ast::Ty);
|
2020-10-09 17:20:06 -05:00
|
|
|
fn check_generic_arg(a: &ast::GenericArg);
|
2019-01-18 00:40:55 -06:00
|
|
|
fn check_generic_param(a: &ast::GenericParam);
|
|
|
|
fn check_generics(a: &ast::Generics);
|
|
|
|
fn check_where_predicate(a: &ast::WherePredicate);
|
|
|
|
fn check_poly_trait_ref(a: &ast::PolyTraitRef,
|
|
|
|
b: &ast::TraitBoundModifier);
|
2020-02-29 11:37:32 -06:00
|
|
|
fn check_fn(a: rustc_ast::visit::FnKind<'_>, c: Span, d_: ast::NodeId);
|
2019-01-18 00:40:55 -06:00
|
|
|
fn check_fn_post(
|
2020-02-29 11:37:32 -06:00
|
|
|
a: rustc_ast::visit::FnKind<'_>,
|
2019-01-18 00:40:55 -06:00
|
|
|
c: Span,
|
|
|
|
d: ast::NodeId
|
|
|
|
);
|
2019-12-07 17:08:09 -06:00
|
|
|
fn check_trait_item(a: &ast::AssocItem);
|
|
|
|
fn check_trait_item_post(a: &ast::AssocItem);
|
|
|
|
fn check_impl_item(a: &ast::AssocItem);
|
|
|
|
fn check_impl_item_post(a: &ast::AssocItem);
|
2019-08-24 11:54:40 -05:00
|
|
|
fn check_struct_def(a: &ast::VariantData);
|
|
|
|
fn check_struct_def_post(a: &ast::VariantData);
|
2019-01-18 00:40:55 -06:00
|
|
|
fn check_struct_field(a: &ast::StructField);
|
2019-08-24 11:54:40 -05:00
|
|
|
fn check_variant(a: &ast::Variant);
|
|
|
|
fn check_variant_post(a: &ast::Variant);
|
2019-01-18 00:40:55 -06:00
|
|
|
fn check_lifetime(a: &ast::Lifetime);
|
|
|
|
fn check_path(a: &ast::Path, b: ast::NodeId);
|
|
|
|
fn check_attribute(a: &ast::Attribute);
|
|
|
|
fn check_mac_def(a: &ast::MacroDef, b: ast::NodeId);
|
2020-02-29 10:32:20 -06:00
|
|
|
fn check_mac(a: &ast::MacCall);
|
2019-01-18 00:40:55 -06:00
|
|
|
|
|
|
|
/// Called when entering a syntax node that can have lint attributes such
|
|
|
|
/// as `#[allow(...)]`. Called with *all* the attributes of that node.
|
|
|
|
fn enter_lint_attrs(a: &[ast::Attribute]);
|
|
|
|
|
|
|
|
/// Counterpart to `enter_lint_attrs`.
|
|
|
|
fn exit_lint_attrs(a: &[ast::Attribute]);
|
|
|
|
]);
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! expand_early_lint_pass_methods {
|
|
|
|
($context:ty, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
|
|
|
|
$(#[inline(always)] fn $name(&mut self, _: $context, $(_: $arg),*) {})*
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! declare_early_lint_pass {
|
|
|
|
([], [$($methods:tt)*]) => (
|
|
|
|
pub trait EarlyLintPass: LintPass {
|
|
|
|
expand_early_lint_pass_methods!(&EarlyContext<'_>, [$($methods)*]);
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
early_lint_methods!(declare_early_lint_pass, []);
|
|
|
|
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! expand_combined_early_lint_pass_method {
|
|
|
|
([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({
|
|
|
|
$($self.$passes.$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: &EarlyContext<'_>, $($param: $arg),*) {
|
|
|
|
expand_combined_early_lint_pass_method!($passes, self, $name, (context, $($param),*));
|
|
|
|
})*
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! declare_combined_early_lint_pass {
|
|
|
|
([$v:vis $name:ident, [$($passes:ident: $constructor:expr,)*]], $methods:tt) => (
|
|
|
|
#[allow(non_snake_case)]
|
|
|
|
$v struct $name {
|
|
|
|
$($passes: $passes,)*
|
|
|
|
}
|
|
|
|
|
|
|
|
impl $name {
|
|
|
|
$v fn new() -> Self {
|
|
|
|
Self {
|
|
|
|
$($passes: $constructor,)*
|
|
|
|
}
|
|
|
|
}
|
2019-10-07 17:04:05 -05:00
|
|
|
|
|
|
|
$v fn get_lints() -> LintArray {
|
|
|
|
let mut lints = Vec::new();
|
|
|
|
$(lints.extend_from_slice(&$passes::get_lints());)*
|
|
|
|
lints
|
|
|
|
}
|
2019-01-18 00:40:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
impl EarlyLintPass for $name {
|
|
|
|
expand_combined_early_lint_pass_methods!([$($passes),*], $methods);
|
|
|
|
}
|
|
|
|
|
2020-01-09 00:52:01 -06:00
|
|
|
#[allow(rustc::lint_pass_impl_without_macro)]
|
2019-01-18 00:40:55 -06:00
|
|
|
impl LintPass for $name {
|
|
|
|
fn name(&self) -> &'static str {
|
|
|
|
panic!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
2014-06-02 17:27:15 -05:00
|
|
|
}
|
|
|
|
|
2014-06-06 17:49:48 -05:00
|
|
|
/// A lint pass boxed up as a trait object.
|
2018-03-02 23:18:09 -06:00
|
|
|
pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + sync::Sync + 'static>;
|
2019-12-24 16:38:22 -06:00
|
|
|
pub type LateLintPassObject =
|
2020-06-25 15:41:36 -05:00
|
|
|
Box<dyn for<'tcx> LateLintPass<'tcx> + sync::Send + sync::Sync + 'static>;
|