1 use crate::context
::{EarlyContext, LateContext}
;
3 use rustc_data_structures
::sync
;
5 use rustc_session
::lint
::builtin
::HardwiredLints
;
6 use rustc_session
::lint
::LintPass
;
11 macro_rules
! late_lint_methods
{
12 ($
macro:path
, $args
:tt
, [$hir
:tt
]) => (
13 $
macro!($args
, [$hir
], [
14 fn check_param(a
: &$hir hir
::Param
<$hir
>);
15 fn check_body(a
: &$hir hir
::Body
<$hir
>);
16 fn check_body_post(a
: &$hir hir
::Body
<$hir
>);
17 fn check_name(a
: Span
, b
: ast
::Name
);
18 fn check_crate(a
: &$hir hir
::Crate
<$hir
>);
19 fn check_crate_post(a
: &$hir hir
::Crate
<$hir
>);
20 fn check_mod(a
: &$hir hir
::Mod
<$hir
>, b
: Span
, c
: hir
::HirId
);
21 fn check_mod_post(a
: &$hir hir
::Mod
<$hir
>, b
: Span
, c
: hir
::HirId
);
22 fn check_foreign_item(a
: &$hir hir
::ForeignItem
<$hir
>);
23 fn check_foreign_item_post(a
: &$hir hir
::ForeignItem
<$hir
>);
24 fn check_item(a
: &$hir hir
::Item
<$hir
>);
25 fn check_item_post(a
: &$hir hir
::Item
<$hir
>);
26 fn check_local(a
: &$hir hir
::Local
<$hir
>);
27 fn check_block(a
: &$hir hir
::Block
<$hir
>);
28 fn check_block_post(a
: &$hir hir
::Block
<$hir
>);
29 fn check_stmt(a
: &$hir hir
::Stmt
<$hir
>);
30 fn check_arm(a
: &$hir hir
::Arm
<$hir
>);
31 fn check_pat(a
: &$hir hir
::Pat
<$hir
>);
32 fn check_expr(a
: &$hir hir
::Expr
<$hir
>);
33 fn check_expr_post(a
: &$hir hir
::Expr
<$hir
>);
34 fn check_ty(a
: &$hir hir
::Ty
<$hir
>);
35 fn check_generic_param(a
: &$hir hir
::GenericParam
<$hir
>);
36 fn check_generics(a
: &$hir hir
::Generics
<$hir
>);
37 fn check_where_predicate(a
: &$hir hir
::WherePredicate
<$hir
>);
38 fn check_poly_trait_ref(a
: &$hir hir
::PolyTraitRef
<$hir
>, b
: hir
::TraitBoundModifier
);
40 a
: rustc_hir
::intravisit
::FnKind
<$hir
>,
41 b
: &$hir hir
::FnDecl
<$hir
>,
42 c
: &$hir hir
::Body
<$hir
>,
46 a
: rustc_hir
::intravisit
::FnKind
<$hir
>,
47 b
: &$hir hir
::FnDecl
<$hir
>,
48 c
: &$hir hir
::Body
<$hir
>,
52 fn check_trait_item(a
: &$hir hir
::TraitItem
<$hir
>);
53 fn check_trait_item_post(a
: &$hir hir
::TraitItem
<$hir
>);
54 fn check_impl_item(a
: &$hir hir
::ImplItem
<$hir
>);
55 fn check_impl_item_post(a
: &$hir hir
::ImplItem
<$hir
>);
56 fn check_struct_def(a
: &$hir hir
::VariantData
<$hir
>);
57 fn check_struct_def_post(a
: &$hir hir
::VariantData
<$hir
>);
58 fn check_struct_field(a
: &$hir hir
::StructField
<$hir
>);
59 fn check_variant(a
: &$hir hir
::Variant
<$hir
>);
60 fn check_variant_post(a
: &$hir hir
::Variant
<$hir
>);
61 fn check_lifetime(a
: &$hir hir
::Lifetime
);
62 fn check_path(a
: &$hir hir
::Path
<$hir
>, b
: hir
::HirId
);
63 fn check_attribute(a
: &$hir ast
::Attribute
);
65 /// Called when entering a syntax node that can have lint attributes such
66 /// as `#[allow(...)]`. Called with *all* the attributes of that node.
67 fn enter_lint_attrs(a
: &$hir
[ast
::Attribute
]);
69 /// Counterpart to `enter_lint_attrs`.
70 fn exit_lint_attrs(a
: &$hir
[ast
::Attribute
]);
75 /// Trait for types providing lint checks.
77 /// Each `check` method checks a single syntax node, and should not
78 /// invoke methods recursively (unlike `Visitor`). By default they
81 // FIXME: eliminate the duplication with `Visitor`. But this also
82 // contains a few lint-specific methods with no equivalent in `Visitor`.
84 macro_rules
! expand_lint_pass_methods
{
85 ($context
:ty
, [$
($
(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
86 $
(#[inline(always)] fn $name(&mut self, _: $context, $(_: $arg),*) {})*
90 macro_rules
! declare_late_lint_pass
{
91 ([], [$hir
:tt
], [$
($methods
:tt
)*]) => (
92 pub trait LateLintPass
<'a
, $hir
>: LintPass
{
93 expand_lint_pass_methods
!(&LateContext
<'a
, $hir
>, [$
($methods
)*]);
98 late_lint_methods
!(declare_late_lint_pass
, [], ['tcx
]);
100 impl LateLintPass
<'_
, '_
> for HardwiredLints {}
103 macro_rules
! expand_combined_late_lint_pass_method
{
104 ([$
($passes
:ident
),*], $
self: ident
, $name
: ident
, $params
:tt
) => ({
105 $
($
self.$passes
.$name $params
;)*
110 macro_rules
! expand_combined_late_lint_pass_methods
{
111 ($passes
:tt
, [$
($
(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
112 $
(fn $
name(&mut self, context
: &LateContext
<'a
, 'tcx
>, $
($param
: $arg
),*) {
113 expand_combined_late_lint_pass_method
!($passes
, self, $name
, (context
, $
($param
),*));
119 macro_rules
! declare_combined_late_lint_pass
{
120 ([$v
:vis $name
:ident
, [$
($passes
:ident
: $constructor
:expr
,)*]], [$hir
:tt
], $methods
:tt
) => (
121 #[allow(non_snake_case)]
123 $
($passes
: $passes
,)*
127 $v
fn new() -> Self {
129 $
($passes
: $constructor
,)*
133 $v
fn get_lints() -> LintArray
{
134 let mut lints
= Vec
::new();
135 $
(lints
.extend_from_slice(&$passes
::get_lints());)*
140 impl<'a
, 'tcx
> LateLintPass
<'a
, 'tcx
> for $name
{
141 expand_combined_late_lint_pass_methods
!([$
($passes
),*], $methods
);
144 #[allow(rustc::lint_pass_impl_without_macro)]
145 impl LintPass
for $name
{
146 fn name(&self) -> &'
static str {
154 macro_rules
! early_lint_methods
{
155 ($
macro:path
, $args
:tt
) => (
157 fn check_param(a
: &ast
::Param
);
158 fn check_ident(a
: ast
::Ident
);
159 fn check_crate(a
: &ast
::Crate
);
160 fn check_crate_post(a
: &ast
::Crate
);
161 fn check_mod(a
: &ast
::Mod
, b
: Span
, c
: ast
::NodeId
);
162 fn check_mod_post(a
: &ast
::Mod
, b
: Span
, c
: ast
::NodeId
);
163 fn check_foreign_item(a
: &ast
::ForeignItem
);
164 fn check_foreign_item_post(a
: &ast
::ForeignItem
);
165 fn check_item(a
: &ast
::Item
);
166 fn check_item_post(a
: &ast
::Item
);
167 fn check_local(a
: &ast
::Local
);
168 fn check_block(a
: &ast
::Block
);
169 fn check_block_post(a
: &ast
::Block
);
170 fn check_stmt(a
: &ast
::Stmt
);
171 fn check_arm(a
: &ast
::Arm
);
172 fn check_pat(a
: &ast
::Pat
);
173 fn check_pat_post(a
: &ast
::Pat
);
174 fn check_expr(a
: &ast
::Expr
);
175 fn check_expr_post(a
: &ast
::Expr
);
176 fn check_ty(a
: &ast
::Ty
);
177 fn check_generic_param(a
: &ast
::GenericParam
);
178 fn check_generics(a
: &ast
::Generics
);
179 fn check_where_predicate(a
: &ast
::WherePredicate
);
180 fn check_poly_trait_ref(a
: &ast
::PolyTraitRef
,
181 b
: &ast
::TraitBoundModifier
);
182 fn check_fn(a
: syntax
::visit
::FnKind
<'_
>, b
: &ast
::FnDecl
, c
: Span
, d_
: ast
::NodeId
);
184 a
: syntax
::visit
::FnKind
<'_
>,
189 fn check_trait_item(a
: &ast
::AssocItem
);
190 fn check_trait_item_post(a
: &ast
::AssocItem
);
191 fn check_impl_item(a
: &ast
::AssocItem
);
192 fn check_impl_item_post(a
: &ast
::AssocItem
);
193 fn check_struct_def(a
: &ast
::VariantData
);
194 fn check_struct_def_post(a
: &ast
::VariantData
);
195 fn check_struct_field(a
: &ast
::StructField
);
196 fn check_variant(a
: &ast
::Variant
);
197 fn check_variant_post(a
: &ast
::Variant
);
198 fn check_lifetime(a
: &ast
::Lifetime
);
199 fn check_path(a
: &ast
::Path
, b
: ast
::NodeId
);
200 fn check_attribute(a
: &ast
::Attribute
);
201 fn check_mac_def(a
: &ast
::MacroDef
, b
: ast
::NodeId
);
202 fn check_mac(a
: &ast
::Mac
);
204 /// Called when entering a syntax node that can have lint attributes such
205 /// as `#[allow(...)]`. Called with *all* the attributes of that node.
206 fn enter_lint_attrs(a
: &[ast
::Attribute
]);
208 /// Counterpart to `enter_lint_attrs`.
209 fn exit_lint_attrs(a
: &[ast
::Attribute
]);
214 macro_rules
! expand_early_lint_pass_methods
{
215 ($context
:ty
, [$
($
(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
216 $
(#[inline(always)] fn $name(&mut self, _: $context, $(_: $arg),*) {})*
220 macro_rules
! declare_early_lint_pass
{
221 ([], [$
($methods
:tt
)*]) => (
222 pub trait EarlyLintPass
: LintPass
{
223 expand_early_lint_pass_methods
!(&EarlyContext
<'_
>, [$
($methods
)*]);
228 early_lint_methods
!(declare_early_lint_pass
, []);
231 macro_rules
! expand_combined_early_lint_pass_method
{
232 ([$
($passes
:ident
),*], $
self: ident
, $name
: ident
, $params
:tt
) => ({
233 $
($
self.$passes
.$name $params
;)*
238 macro_rules
! expand_combined_early_lint_pass_methods
{
239 ($passes
:tt
, [$
($
(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
240 $
(fn $
name(&mut self, context
: &EarlyContext
<'_
>, $
($param
: $arg
),*) {
241 expand_combined_early_lint_pass_method
!($passes
, self, $name
, (context
, $
($param
),*));
247 macro_rules
! declare_combined_early_lint_pass
{
248 ([$v
:vis $name
:ident
, [$
($passes
:ident
: $constructor
:expr
,)*]], $methods
:tt
) => (
249 #[allow(non_snake_case)]
251 $
($passes
: $passes
,)*
255 $v
fn new() -> Self {
257 $
($passes
: $constructor
,)*
261 $v
fn get_lints() -> LintArray
{
262 let mut lints
= Vec
::new();
263 $
(lints
.extend_from_slice(&$passes
::get_lints());)*
268 impl EarlyLintPass
for $name
{
269 expand_combined_early_lint_pass_methods
!([$
($passes
),*], $methods
);
272 #[allow(rustc::lint_pass_impl_without_macro)]
273 impl LintPass
for $name
{
274 fn name(&self) -> &'
static str {
281 /// A lint pass boxed up as a trait object.
282 pub type EarlyLintPassObject
= Box
<dyn EarlyLintPass
+ sync
::Send
+ sync
::Sync
+ '
static>;
283 pub type LateLintPassObject
=
284 Box
<dyn for<'a
, 'tcx
> LateLintPass
<'a
, 'tcx
> + sync
::Send
+ sync
::Sync
+ '
static>;