]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_lint/src/passes.rs
Merge tag 'debian/1.52.1+dfsg1-1_exp2' into proxmox/buster
[rustc.git] / compiler / rustc_lint / src / passes.rs
CommitLineData
dfeec247
XL
1use crate::context::{EarlyContext, LateContext};
2
3dfed10e 3use rustc_ast as ast;
dfeec247
XL
4use rustc_data_structures::sync;
5use rustc_hir as hir;
6use rustc_session::lint::builtin::HardwiredLints;
7use rustc_session::lint::LintPass;
f9f354fc 8use rustc_span::symbol::{Ident, Symbol};
dfeec247 9use rustc_span::Span;
dfeec247
XL
10
11#[macro_export]
12macro_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
86macro_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
92macro_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
100late_lint_methods!(declare_late_lint_pass, [], ['tcx]);
101
f035d41b 102impl LateLintPass<'_> for HardwiredLints {}
dfeec247
XL
103
104#[macro_export]
105macro_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]
112macro_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]
121macro_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]
156macro_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
215macro_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
221macro_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
229early_lint_methods!(declare_early_lint_pass, []);
230
231#[macro_export]
232macro_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]
239macro_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]
248macro_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.
283pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + sync::Sync + 'static>;
284pub type LateLintPassObject =
f035d41b 285 Box<dyn for<'tcx> LateLintPass<'tcx> + sync::Send + sync::Sync + 'static>;