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