1use rustc_session::lint::LintPass;
2
3use crate::context::{EarlyContext, LateContext};
4
5#[macro_export]
6macro_rules! late_lint_methods {
7 ($macro:path, $args:tt) => (
8 $macro!($args, [
10 fn check_body(a: &rustc_hir::Body<'tcx>);
11 fn check_body_post(a: &rustc_hir::Body<'tcx>);
12 fn check_crate();
13 fn check_crate_post();
14 fn check_mod(a: &'tcx rustc_hir::Mod<'tcx>, b: rustc_hir::HirId);
15 fn check_foreign_item(a: &'tcx rustc_hir::ForeignItem<'tcx>);
16 fn check_item(a: &'tcx rustc_hir::Item<'tcx>);
17 fn check_item_post(a: &'tcx rustc_hir::Item<'tcx>);
18 fn check_local(a: &'tcx rustc_hir::LetStmt<'tcx>);
19 fn check_block(a: &'tcx rustc_hir::Block<'tcx>);
20 fn check_block_post(a: &'tcx rustc_hir::Block<'tcx>);
21 fn check_stmt(a: &'tcx rustc_hir::Stmt<'tcx>);
22 fn check_arm(a: &'tcx rustc_hir::Arm<'tcx>);
23 fn check_pat(a: &'tcx rustc_hir::Pat<'tcx>);
24 fn check_lit(hir_id: rustc_hir::HirId, a: rustc_hir::Lit, is_negated_pat: bool);
25 fn check_expr(a: &'tcx rustc_hir::Expr<'tcx>);
26 fn check_expr_post(a: &'tcx rustc_hir::Expr<'tcx>);
27 fn check_ty(a: &'tcx rustc_hir::Ty<'tcx, rustc_hir::AmbigArg>);
28 fn check_generic_param(a: &'tcx rustc_hir::GenericParam<'tcx>);
29 fn check_generics(a: &'tcx rustc_hir::Generics<'tcx>);
30 fn check_poly_trait_ref(a: &'tcx rustc_hir::PolyTraitRef<'tcx>);
31 fn check_fn(
32 a: rustc_hir::intravisit::FnKind<'tcx>,
33 b: &'tcx rustc_hir::FnDecl<'tcx>,
34 c: &'tcx rustc_hir::Body<'tcx>,
35 d: rustc_span::Span,
36 e: rustc_span::def_id::LocalDefId);
37 fn check_trait_item(a: &'tcx rustc_hir::TraitItem<'tcx>);
38 fn check_impl_item(a: &'tcx rustc_hir::ImplItem<'tcx>);
39 fn check_impl_item_post(a: &'tcx rustc_hir::ImplItem<'tcx>);
40 fn check_field_def(a: &'tcx rustc_hir::FieldDef<'tcx>);
41 fn check_variant(a: &'tcx rustc_hir::Variant<'tcx>);
42 fn check_path(a: &rustc_hir::Path<'tcx>, b: rustc_hir::HirId);
43 fn check_attribute(a: &'tcx rustc_hir::Attribute);
44 fn check_attributes(a: &'tcx [rustc_hir::Attribute]);
45 fn check_attributes_post(a: &'tcx [rustc_hir::Attribute]);
46 ]);
47 )
48}
49
50macro_rules! declare_late_lint_pass {
60 ([], [$(fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
61 pub trait LateLintPass<'tcx>: LintPass {
62 $(#[inline(always)] fn $name(&mut self, _: &LateContext<'tcx>, $(_: $arg),*) {})*
63 }
64 )
65}
66
67pub trait LateLintPass<'tcx>: LintPass {
#[inline(always)]
fn check_body(&mut self, _: &LateContext<'tcx>,
_: &rustc_hir::Body<'tcx>) {}
#[inline(always)]
fn check_body_post(&mut self, _: &LateContext<'tcx>,
_: &rustc_hir::Body<'tcx>) {}
#[inline(always)]
fn check_crate(&mut self, _: &LateContext<'tcx>) {}
#[inline(always)]
fn check_crate_post(&mut self, _: &LateContext<'tcx>) {}
#[inline(always)]
fn check_mod(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::Mod<'tcx>, _: rustc_hir::HirId) {}
#[inline(always)]
fn check_foreign_item(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::ForeignItem<'tcx>) {}
#[inline(always)]
fn check_item(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::Item<'tcx>) {}
#[inline(always)]
fn check_item_post(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::Item<'tcx>) {}
#[inline(always)]
fn check_local(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::LetStmt<'tcx>) {}
#[inline(always)]
fn check_block(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::Block<'tcx>) {}
#[inline(always)]
fn check_block_post(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::Block<'tcx>) {}
#[inline(always)]
fn check_stmt(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::Stmt<'tcx>) {}
#[inline(always)]
fn check_arm(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::Arm<'tcx>) {}
#[inline(always)]
fn check_pat(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::Pat<'tcx>) {}
#[inline(always)]
fn check_lit(&mut self, _: &LateContext<'tcx>, _: rustc_hir::HirId,
_: rustc_hir::Lit, _: bool) {}
#[inline(always)]
fn check_expr(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::Expr<'tcx>) {}
#[inline(always)]
fn check_expr_post(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::Expr<'tcx>) {}
#[inline(always)]
fn check_ty(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::Ty<'tcx, rustc_hir::AmbigArg>) {}
#[inline(always)]
fn check_generic_param(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::GenericParam<'tcx>) {}
#[inline(always)]
fn check_generics(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::Generics<'tcx>) {}
#[inline(always)]
fn check_poly_trait_ref(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::PolyTraitRef<'tcx>) {}
#[inline(always)]
fn check_fn(&mut self, _: &LateContext<'tcx>,
_: rustc_hir::intravisit::FnKind<'tcx>,
_: &'tcx rustc_hir::FnDecl<'tcx>, _: &'tcx rustc_hir::Body<'tcx>,
_: rustc_span::Span, _: rustc_span::def_id::LocalDefId) {}
#[inline(always)]
fn check_trait_item(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::TraitItem<'tcx>) {}
#[inline(always)]
fn check_impl_item(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::ImplItem<'tcx>) {}
#[inline(always)]
fn check_impl_item_post(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::ImplItem<'tcx>) {}
#[inline(always)]
fn check_field_def(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::FieldDef<'tcx>) {}
#[inline(always)]
fn check_variant(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::Variant<'tcx>) {}
#[inline(always)]
fn check_path(&mut self, _: &LateContext<'tcx>, _: &rustc_hir::Path<'tcx>,
_: rustc_hir::HirId) {}
#[inline(always)]
fn check_attribute(&mut self, _: &LateContext<'tcx>,
_: &'tcx rustc_hir::Attribute) {}
#[inline(always)]
fn check_attributes(&mut self, _: &LateContext<'tcx>,
_: &'tcx [rustc_hir::Attribute]) {}
#[inline(always)]
fn check_attributes_post(&mut self, _: &LateContext<'tcx>,
_: &'tcx [rustc_hir::Attribute]) {}
}late_lint_methods!(declare_late_lint_pass, []);
70
71#[macro_export]
72macro_rules! expand_combined_late_lint_pass_method {
73 ([$($pass:ident),*], $self: ident, $name: ident, $params:tt) => ({
74 $($self.$pass.$name $params;)*
75 })
76}
77
78#[macro_export]
79macro_rules! expand_combined_late_lint_pass_methods {
80 ($passes:tt, [$(fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
81 $(fn $name(&mut self, context: &$crate::LateContext<'tcx>, $($param: $arg),*) {
82 $crate::expand_combined_late_lint_pass_method!($passes, self, $name, (context, $($param),*));
83 })*
84 )
85}
86
87#[macro_export]
93macro_rules! declare_combined_late_lint_pass {
94 ([$v:vis $name:ident, [$($pass:ident: $constructor:expr,)*]], $methods:tt) => (
95 #[allow(non_snake_case)]
96 $v struct $name {
97 $($pass: $pass,)*
98 }
99
100 impl $name {
101 $v fn new() -> Self {
102 Self {
103 $($pass: $constructor,)*
104 }
105 }
106
107 $v fn lint_vec() -> $crate::LintVec {
108 let mut lints = Vec::new();
109 $(lints.extend_from_slice(&$pass::lint_vec());)*
110 lints
111 }
112 }
113
114 impl<'tcx> $crate::LateLintPass<'tcx> for $name {
115 $crate::expand_combined_late_lint_pass_methods!([$($pass),*], $methods);
116 }
117
118 #[allow(rustc::lint_pass_impl_without_macro)]
119 impl $crate::LintPass for $name {
120 fn name(&self) -> &'static str {
121 stringify!($name)
122 }
123 fn get_lints(&self) -> LintVec {
124 $name::lint_vec()
125 }
126 }
127 )
128}
129
130#[macro_export]
131macro_rules! early_lint_methods {
132 ($macro:path, $args:tt) => (
133 $macro!($args, [
135 fn check_param(a: &rustc_ast::Param);
136 fn check_ident(a: &rustc_span::Ident);
137 fn check_crate(a: &rustc_ast::Crate);
138 fn check_crate_post(a: &rustc_ast::Crate);
139 fn check_item(a: &rustc_ast::Item);
140 fn check_item_post(a: &rustc_ast::Item);
141 fn check_local(a: &rustc_ast::Local);
142 fn check_block(a: &rustc_ast::Block);
143 fn check_stmt(a: &rustc_ast::Stmt);
144 fn check_arm(a: &rustc_ast::Arm);
145 fn check_pat(a: &rustc_ast::Pat);
146 fn check_pat_post(a: &rustc_ast::Pat);
147 fn check_expr(a: &rustc_ast::Expr);
148 fn check_expr_post(a: &rustc_ast::Expr);
149 fn check_ty(a: &rustc_ast::Ty);
150 fn check_generic_arg(a: &rustc_ast::GenericArg);
151 fn check_generic_param(a: &rustc_ast::GenericParam);
152 fn check_generics(a: &rustc_ast::Generics);
153 fn check_poly_trait_ref(a: &rustc_ast::PolyTraitRef);
154 fn check_fn(
155 a: rustc_ast::visit::FnKind<'_>,
156 c: rustc_span::Span,
157 d_: rustc_ast::NodeId);
158 fn check_trait_item(a: &rustc_ast::AssocItem);
159 fn check_trait_item_post(a: &rustc_ast::AssocItem);
160 fn check_impl_item(a: &rustc_ast::AssocItem);
161 fn check_impl_item_post(a: &rustc_ast::AssocItem);
162 fn check_variant(a: &rustc_ast::Variant);
163 fn check_attribute(a: &rustc_ast::Attribute);
164 fn check_attributes(a: &[rustc_ast::Attribute]);
165 fn check_attributes_post(a: &[rustc_ast::Attribute]);
166 fn check_mac_def(a: &rustc_ast::MacroDef);
167 fn check_mac(a: &rustc_ast::MacCall);
168 fn check_where_predicate(a: &rustc_ast::WherePredicate);
169 fn check_where_predicate_post(a: &rustc_ast::WherePredicate);
170 ]);
171 )
172}
173
174macro_rules! declare_early_lint_pass {
175 ([], [$(fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
176 pub trait EarlyLintPass: LintPass {
177 $(#[inline(always)] fn $name(&mut self, _: &EarlyContext<'_>, $(_: $arg),*) {})*
178 }
179 )
180}
181
182pub trait EarlyLintPass: LintPass {
#[inline(always)]
fn check_param(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Param) {}
#[inline(always)]
fn check_ident(&mut self, _: &EarlyContext<'_>, _: &rustc_span::Ident) {}
#[inline(always)]
fn check_crate(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Crate) {}
#[inline(always)]
fn check_crate_post(&mut self, _: &EarlyContext<'_>,
_: &rustc_ast::Crate) {}
#[inline(always)]
fn check_item(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Item) {}
#[inline(always)]
fn check_item_post(&mut self, _: &EarlyContext<'_>,
_: &rustc_ast::Item) {}
#[inline(always)]
fn check_local(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Local) {}
#[inline(always)]
fn check_block(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Block) {}
#[inline(always)]
fn check_stmt(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Stmt) {}
#[inline(always)]
fn check_arm(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Arm) {}
#[inline(always)]
fn check_pat(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Pat) {}
#[inline(always)]
fn check_pat_post(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Pat) {}
#[inline(always)]
fn check_expr(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Expr) {}
#[inline(always)]
fn check_expr_post(&mut self, _: &EarlyContext<'_>,
_: &rustc_ast::Expr) {}
#[inline(always)]
fn check_ty(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Ty) {}
#[inline(always)]
fn check_generic_arg(&mut self, _: &EarlyContext<'_>,
_: &rustc_ast::GenericArg) {}
#[inline(always)]
fn check_generic_param(&mut self, _: &EarlyContext<'_>,
_: &rustc_ast::GenericParam) {}
#[inline(always)]
fn check_generics(&mut self, _: &EarlyContext<'_>,
_: &rustc_ast::Generics) {}
#[inline(always)]
fn check_poly_trait_ref(&mut self, _: &EarlyContext<'_>,
_: &rustc_ast::PolyTraitRef) {}
#[inline(always)]
fn check_fn(&mut self, _: &EarlyContext<'_>,
_: rustc_ast::visit::FnKind<'_>, _: rustc_span::Span,
_: rustc_ast::NodeId) {}
#[inline(always)]
fn check_trait_item(&mut self, _: &EarlyContext<'_>,
_: &rustc_ast::AssocItem) {}
#[inline(always)]
fn check_trait_item_post(&mut self, _: &EarlyContext<'_>,
_: &rustc_ast::AssocItem) {}
#[inline(always)]
fn check_impl_item(&mut self, _: &EarlyContext<'_>,
_: &rustc_ast::AssocItem) {}
#[inline(always)]
fn check_impl_item_post(&mut self, _: &EarlyContext<'_>,
_: &rustc_ast::AssocItem) {}
#[inline(always)]
fn check_variant(&mut self, _: &EarlyContext<'_>,
_: &rustc_ast::Variant) {}
#[inline(always)]
fn check_attribute(&mut self, _: &EarlyContext<'_>,
_: &rustc_ast::Attribute) {}
#[inline(always)]
fn check_attributes(&mut self, _: &EarlyContext<'_>,
_: &[rustc_ast::Attribute]) {}
#[inline(always)]
fn check_attributes_post(&mut self, _: &EarlyContext<'_>,
_: &[rustc_ast::Attribute]) {}
#[inline(always)]
fn check_mac_def(&mut self, _: &EarlyContext<'_>,
_: &rustc_ast::MacroDef) {}
#[inline(always)]
fn check_mac(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::MacCall) {}
#[inline(always)]
fn check_where_predicate(&mut self, _: &EarlyContext<'_>,
_: &rustc_ast::WherePredicate) {}
#[inline(always)]
fn check_where_predicate_post(&mut self, _: &EarlyContext<'_>,
_: &rustc_ast::WherePredicate) {}
}early_lint_methods!(declare_early_lint_pass, []);
185
186#[macro_export]
187macro_rules! expand_combined_early_lint_pass_method {
188 ([$($pass:ident),*], $self: ident, $name: ident, $params:tt) => ({
189 $($self.$pass.$name $params;)*
190 })
191}
192
193#[macro_export]
194macro_rules! expand_combined_early_lint_pass_methods {
195 ($passes:tt, [$(fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
196 $(fn $name(&mut self, context: &$crate::EarlyContext<'_>, $($param: $arg),*) {
197 $crate::expand_combined_early_lint_pass_method!($passes, self, $name, (context, $($param),*));
198 })*
199 )
200}
201
202#[macro_export]
208macro_rules! declare_combined_early_lint_pass {
209 ([$v:vis $name:ident, [$($pass:ident: $constructor:expr,)*]], $methods:tt) => (
210 #[allow(non_snake_case)]
211 $v struct $name {
212 $($pass: $pass,)*
213 }
214
215 impl $name {
216 $v fn new() -> Self {
217 Self {
218 $($pass: $constructor,)*
219 }
220 }
221
222 $v fn lint_vec() -> $crate::LintVec {
223 let mut lints = Vec::new();
224 $(lints.extend_from_slice(&$pass::lint_vec());)*
225 lints
226 }
227 }
228
229 impl $crate::EarlyLintPass for $name {
230 $crate::expand_combined_early_lint_pass_methods!([$($pass),*], $methods);
231 }
232
233 #[allow(rustc::lint_pass_impl_without_macro)]
234 impl $crate::LintPass for $name {
235 fn name(&self) -> &'static str {
236 panic!()
237 }
238 fn get_lints(&self) -> LintVec {
239 panic!()
240 }
241 }
242 )
243}
244
245pub(crate) type EarlyLintPassObject = Box<dyn EarlyLintPass>;
247pub(crate) type LateLintPassObject<'tcx> = Box<dyn LateLintPass<'tcx> + 'tcx>;