]>
Commit | Line | Data |
---|---|---|
dfeec247 XL |
1 | use crate::context::{EarlyContext, LateContext}; |
2 | ||
3dfed10e | 3 | use rustc_ast as ast; |
dfeec247 XL |
4 | use rustc_data_structures::sync; |
5 | use rustc_hir as hir; | |
6 | use rustc_session::lint::builtin::HardwiredLints; | |
7 | use rustc_session::lint::LintPass; | |
f9f354fc | 8 | use rustc_span::symbol::{Ident, Symbol}; |
dfeec247 | 9 | use rustc_span::Span; |
dfeec247 XL |
10 | |
11 | #[macro_export] | |
12 | macro_rules! late_lint_methods { | |
13 | ($macro:path, $args:tt, [$hir:tt]) => ( | |
14 | $macro!($args, [$hir], [ | |
15 | fn check_param(a: &$hir hir::Param<$hir>); | |
16 | fn check_body(a: &$hir hir::Body<$hir>); | |
17 | fn check_body_post(a: &$hir hir::Body<$hir>); | |
f9f354fc | 18 | fn check_name(a: Span, b: Symbol); |
dfeec247 XL |
19 | fn check_crate(a: &$hir hir::Crate<$hir>); |
20 | fn check_crate_post(a: &$hir hir::Crate<$hir>); | |
21 | fn check_mod(a: &$hir hir::Mod<$hir>, b: Span, c: hir::HirId); | |
22 | fn check_mod_post(a: &$hir hir::Mod<$hir>, b: Span, c: hir::HirId); | |
23 | fn check_foreign_item(a: &$hir hir::ForeignItem<$hir>); | |
24 | fn check_foreign_item_post(a: &$hir hir::ForeignItem<$hir>); | |
25 | fn check_item(a: &$hir hir::Item<$hir>); | |
26 | fn check_item_post(a: &$hir hir::Item<$hir>); | |
27 | fn check_local(a: &$hir hir::Local<$hir>); | |
28 | fn check_block(a: &$hir hir::Block<$hir>); | |
29 | fn check_block_post(a: &$hir hir::Block<$hir>); | |
30 | fn check_stmt(a: &$hir hir::Stmt<$hir>); | |
31 | fn check_arm(a: &$hir hir::Arm<$hir>); | |
32 | fn check_pat(a: &$hir hir::Pat<$hir>); | |
33 | fn check_expr(a: &$hir hir::Expr<$hir>); | |
34 | fn check_expr_post(a: &$hir hir::Expr<$hir>); | |
35 | fn check_ty(a: &$hir hir::Ty<$hir>); | |
29967ef6 | 36 | fn check_generic_arg(a: &$hir hir::GenericArg<$hir>); |
dfeec247 XL |
37 | fn check_generic_param(a: &$hir hir::GenericParam<$hir>); |
38 | fn check_generics(a: &$hir hir::Generics<$hir>); | |
39 | fn check_where_predicate(a: &$hir hir::WherePredicate<$hir>); | |
40 | fn check_poly_trait_ref(a: &$hir hir::PolyTraitRef<$hir>, b: hir::TraitBoundModifier); | |
41 | fn check_fn( | |
42 | a: rustc_hir::intravisit::FnKind<$hir>, | |
43 | b: &$hir hir::FnDecl<$hir>, | |
44 | c: &$hir hir::Body<$hir>, | |
45 | d: Span, | |
46 | e: hir::HirId); | |
47 | fn check_fn_post( | |
48 | a: rustc_hir::intravisit::FnKind<$hir>, | |
49 | b: &$hir hir::FnDecl<$hir>, | |
50 | c: &$hir hir::Body<$hir>, | |
51 | d: Span, | |
52 | e: hir::HirId | |
53 | ); | |
54 | fn check_trait_item(a: &$hir hir::TraitItem<$hir>); | |
55 | fn check_trait_item_post(a: &$hir hir::TraitItem<$hir>); | |
56 | fn check_impl_item(a: &$hir hir::ImplItem<$hir>); | |
57 | fn check_impl_item_post(a: &$hir hir::ImplItem<$hir>); | |
58 | fn check_struct_def(a: &$hir hir::VariantData<$hir>); | |
59 | fn check_struct_def_post(a: &$hir hir::VariantData<$hir>); | |
6a06907d | 60 | fn check_field_def(a: &$hir hir::FieldDef<$hir>); |
dfeec247 XL |
61 | fn check_variant(a: &$hir hir::Variant<$hir>); |
62 | fn check_variant_post(a: &$hir hir::Variant<$hir>); | |
63 | fn check_lifetime(a: &$hir hir::Lifetime); | |
64 | fn check_path(a: &$hir hir::Path<$hir>, b: hir::HirId); | |
65 | fn check_attribute(a: &$hir ast::Attribute); | |
66 | ||
67 | /// Called when entering a syntax node that can have lint attributes such | |
68 | /// as `#[allow(...)]`. Called with *all* the attributes of that node. | |
69 | fn enter_lint_attrs(a: &$hir [ast::Attribute]); | |
70 | ||
71 | /// Counterpart to `enter_lint_attrs`. | |
72 | fn exit_lint_attrs(a: &$hir [ast::Attribute]); | |
73 | ]); | |
74 | ) | |
75 | } | |
76 | ||
77 | /// Trait for types providing lint checks. | |
78 | /// | |
79 | /// Each `check` method checks a single syntax node, and should not | |
80 | /// invoke methods recursively (unlike `Visitor`). By default they | |
81 | /// do nothing. | |
82 | // | |
83 | // FIXME: eliminate the duplication with `Visitor`. But this also | |
84 | // contains a few lint-specific methods with no equivalent in `Visitor`. | |
85 | ||
86 | macro_rules! expand_lint_pass_methods { | |
87 | ($context:ty, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( | |
88 | $(#[inline(always)] fn $name(&mut self, _: $context, $(_: $arg),*) {})* | |
89 | ) | |
90 | } | |
91 | ||
92 | macro_rules! declare_late_lint_pass { | |
93 | ([], [$hir:tt], [$($methods:tt)*]) => ( | |
f035d41b XL |
94 | pub trait LateLintPass<$hir>: LintPass { |
95 | expand_lint_pass_methods!(&LateContext<$hir>, [$($methods)*]); | |
dfeec247 XL |
96 | } |
97 | ) | |
98 | } | |
99 | ||
100 | late_lint_methods!(declare_late_lint_pass, [], ['tcx]); | |
101 | ||
f035d41b | 102 | impl LateLintPass<'_> for HardwiredLints {} |
dfeec247 XL |
103 | |
104 | #[macro_export] | |
105 | macro_rules! expand_combined_late_lint_pass_method { | |
106 | ([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({ | |
107 | $($self.$passes.$name $params;)* | |
108 | }) | |
109 | } | |
110 | ||
111 | #[macro_export] | |
112 | macro_rules! expand_combined_late_lint_pass_methods { | |
113 | ($passes:tt, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( | |
f035d41b | 114 | $(fn $name(&mut self, context: &LateContext<'tcx>, $($param: $arg),*) { |
dfeec247 XL |
115 | expand_combined_late_lint_pass_method!($passes, self, $name, (context, $($param),*)); |
116 | })* | |
117 | ) | |
118 | } | |
119 | ||
120 | #[macro_export] | |
121 | macro_rules! declare_combined_late_lint_pass { | |
122 | ([$v:vis $name:ident, [$($passes:ident: $constructor:expr,)*]], [$hir:tt], $methods:tt) => ( | |
123 | #[allow(non_snake_case)] | |
124 | $v struct $name { | |
125 | $($passes: $passes,)* | |
126 | } | |
127 | ||
128 | impl $name { | |
129 | $v fn new() -> Self { | |
130 | Self { | |
131 | $($passes: $constructor,)* | |
132 | } | |
133 | } | |
134 | ||
135 | $v fn get_lints() -> LintArray { | |
136 | let mut lints = Vec::new(); | |
137 | $(lints.extend_from_slice(&$passes::get_lints());)* | |
138 | lints | |
139 | } | |
140 | } | |
141 | ||
f035d41b | 142 | impl<'tcx> LateLintPass<'tcx> for $name { |
dfeec247 XL |
143 | expand_combined_late_lint_pass_methods!([$($passes),*], $methods); |
144 | } | |
145 | ||
146 | #[allow(rustc::lint_pass_impl_without_macro)] | |
147 | impl LintPass for $name { | |
148 | fn name(&self) -> &'static str { | |
149 | panic!() | |
150 | } | |
151 | } | |
152 | ) | |
153 | } | |
154 | ||
155 | #[macro_export] | |
156 | macro_rules! early_lint_methods { | |
157 | ($macro:path, $args:tt) => ( | |
158 | $macro!($args, [ | |
159 | fn check_param(a: &ast::Param); | |
f9f354fc | 160 | fn check_ident(a: Ident); |
dfeec247 XL |
161 | fn check_crate(a: &ast::Crate); |
162 | fn check_crate_post(a: &ast::Crate); | |
dfeec247 XL |
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); | |
ba9703b0 | 173 | fn check_anon_const(a: &ast::AnonConst); |
dfeec247 XL |
174 | fn check_pat_post(a: &ast::Pat); |
175 | fn check_expr(a: &ast::Expr); | |
176 | fn check_expr_post(a: &ast::Expr); | |
177 | fn check_ty(a: &ast::Ty); | |
29967ef6 | 178 | fn check_generic_arg(a: &ast::GenericArg); |
dfeec247 XL |
179 | fn check_generic_param(a: &ast::GenericParam); |
180 | fn check_generics(a: &ast::Generics); | |
181 | fn check_where_predicate(a: &ast::WherePredicate); | |
182 | fn check_poly_trait_ref(a: &ast::PolyTraitRef, | |
183 | b: &ast::TraitBoundModifier); | |
74b04a01 | 184 | fn check_fn(a: rustc_ast::visit::FnKind<'_>, c: Span, d_: ast::NodeId); |
dfeec247 | 185 | fn check_fn_post( |
74b04a01 | 186 | a: rustc_ast::visit::FnKind<'_>, |
dfeec247 XL |
187 | c: Span, |
188 | d: ast::NodeId | |
189 | ); | |
190 | fn check_trait_item(a: &ast::AssocItem); | |
191 | fn check_trait_item_post(a: &ast::AssocItem); | |
192 | fn check_impl_item(a: &ast::AssocItem); | |
193 | fn check_impl_item_post(a: &ast::AssocItem); | |
194 | fn check_struct_def(a: &ast::VariantData); | |
195 | fn check_struct_def_post(a: &ast::VariantData); | |
6a06907d | 196 | fn check_field_def(a: &ast::FieldDef); |
dfeec247 XL |
197 | fn check_variant(a: &ast::Variant); |
198 | fn check_variant_post(a: &ast::Variant); | |
199 | fn check_lifetime(a: &ast::Lifetime); | |
200 | fn check_path(a: &ast::Path, b: ast::NodeId); | |
201 | fn check_attribute(a: &ast::Attribute); | |
202 | fn check_mac_def(a: &ast::MacroDef, b: ast::NodeId); | |
ba9703b0 | 203 | fn check_mac(a: &ast::MacCall); |
dfeec247 XL |
204 | |
205 | /// Called when entering a syntax node that can have lint attributes such | |
206 | /// as `#[allow(...)]`. Called with *all* the attributes of that node. | |
207 | fn enter_lint_attrs(a: &[ast::Attribute]); | |
208 | ||
209 | /// Counterpart to `enter_lint_attrs`. | |
210 | fn exit_lint_attrs(a: &[ast::Attribute]); | |
211 | ]); | |
212 | ) | |
213 | } | |
214 | ||
215 | macro_rules! expand_early_lint_pass_methods { | |
216 | ($context:ty, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( | |
217 | $(#[inline(always)] fn $name(&mut self, _: $context, $(_: $arg),*) {})* | |
218 | ) | |
219 | } | |
220 | ||
221 | macro_rules! declare_early_lint_pass { | |
222 | ([], [$($methods:tt)*]) => ( | |
223 | pub trait EarlyLintPass: LintPass { | |
224 | expand_early_lint_pass_methods!(&EarlyContext<'_>, [$($methods)*]); | |
225 | } | |
226 | ) | |
227 | } | |
228 | ||
229 | early_lint_methods!(declare_early_lint_pass, []); | |
230 | ||
231 | #[macro_export] | |
232 | macro_rules! expand_combined_early_lint_pass_method { | |
233 | ([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({ | |
234 | $($self.$passes.$name $params;)* | |
235 | }) | |
236 | } | |
237 | ||
238 | #[macro_export] | |
239 | macro_rules! expand_combined_early_lint_pass_methods { | |
240 | ($passes:tt, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( | |
241 | $(fn $name(&mut self, context: &EarlyContext<'_>, $($param: $arg),*) { | |
242 | expand_combined_early_lint_pass_method!($passes, self, $name, (context, $($param),*)); | |
243 | })* | |
244 | ) | |
245 | } | |
246 | ||
247 | #[macro_export] | |
248 | macro_rules! declare_combined_early_lint_pass { | |
249 | ([$v:vis $name:ident, [$($passes:ident: $constructor:expr,)*]], $methods:tt) => ( | |
250 | #[allow(non_snake_case)] | |
251 | $v struct $name { | |
252 | $($passes: $passes,)* | |
253 | } | |
254 | ||
255 | impl $name { | |
256 | $v fn new() -> Self { | |
257 | Self { | |
258 | $($passes: $constructor,)* | |
259 | } | |
260 | } | |
261 | ||
262 | $v fn get_lints() -> LintArray { | |
263 | let mut lints = Vec::new(); | |
264 | $(lints.extend_from_slice(&$passes::get_lints());)* | |
265 | lints | |
266 | } | |
267 | } | |
268 | ||
269 | impl EarlyLintPass for $name { | |
270 | expand_combined_early_lint_pass_methods!([$($passes),*], $methods); | |
271 | } | |
272 | ||
273 | #[allow(rustc::lint_pass_impl_without_macro)] | |
274 | impl LintPass for $name { | |
275 | fn name(&self) -> &'static str { | |
276 | panic!() | |
277 | } | |
278 | } | |
279 | ) | |
280 | } | |
281 | ||
282 | /// A lint pass boxed up as a trait object. | |
283 | pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + sync::Sync + 'static>; | |
284 | pub type LateLintPassObject = | |
f035d41b | 285 | Box<dyn for<'tcx> LateLintPass<'tcx> + sync::Send + sync::Sync + 'static>; |