@@ -35,7 +35,7 @@ use rustc_data_structures::sync::{self, Lrc};
3535
3636use errors:: { DiagnosticBuilder , DiagnosticId } ;
3737use hir:: def_id:: { CrateNum , LOCAL_CRATE } ;
38- use hir:: intravisit:: { self , FnKind } ;
38+ use hir:: intravisit;
3939use hir;
4040use lint:: builtin:: BuiltinLintDiagnostics ;
4141use session:: { Session , DiagnosticMessageId } ;
@@ -123,12 +123,11 @@ macro_rules! declare_lint {
123123#[ macro_export]
124124macro_rules! lint_array {
125125 ( $( $lint: expr ) ,* $( , ) ?) => { {
126- static ARRAY : LintArray = & [ $( & $lint ) ,* ] ;
127- ARRAY
126+ vec![ $( $lint) ,* ]
128127 } }
129128}
130129
131- pub type LintArray = & ' static [ & ' static & ' static Lint ] ;
130+ pub type LintArray = Vec < & ' static Lint > ;
132131
133132pub trait LintPass {
134133 /// Get descriptions of the lints this `LintPass` object can emit.
@@ -140,6 +139,80 @@ pub trait LintPass {
140139 fn get_lints ( & self ) -> LintArray ;
141140}
142141
142+ #[ macro_export]
143+ macro_rules! late_lint_methods {
144+ ( $macro: path, $args: tt, [ $hir: tt] ) => (
145+ $macro!( $args, [ $hir] , [
146+ fn check_body( a: & $hir hir:: Body ) ;
147+ fn check_body_post( a: & $hir hir:: Body ) ;
148+ fn check_name( a: Span , b: ast:: Name ) ;
149+ fn check_crate( a: & $hir hir:: Crate ) ;
150+ fn check_crate_post( a: & $hir hir:: Crate ) ;
151+ fn check_mod( a: & $hir hir:: Mod , b: Span , c: ast:: NodeId ) ;
152+ fn check_mod_post( a: & $hir hir:: Mod , b: Span , c: ast:: NodeId ) ;
153+ fn check_foreign_item( a: & $hir hir:: ForeignItem ) ;
154+ fn check_foreign_item_post( a: & $hir hir:: ForeignItem ) ;
155+ fn check_item( a: & $hir hir:: Item ) ;
156+ fn check_item_post( a: & $hir hir:: Item ) ;
157+ fn check_local( a: & $hir hir:: Local ) ;
158+ fn check_block( a: & $hir hir:: Block ) ;
159+ fn check_block_post( a: & $hir hir:: Block ) ;
160+ fn check_stmt( a: & $hir hir:: Stmt ) ;
161+ fn check_arm( a: & $hir hir:: Arm ) ;
162+ fn check_pat( a: & $hir hir:: Pat ) ;
163+ fn check_decl( a: & $hir hir:: Decl ) ;
164+ fn check_expr( a: & $hir hir:: Expr ) ;
165+ fn check_expr_post( a: & $hir hir:: Expr ) ;
166+ fn check_ty( a: & $hir hir:: Ty ) ;
167+ fn check_generic_param( a: & $hir hir:: GenericParam ) ;
168+ fn check_generics( a: & $hir hir:: Generics ) ;
169+ fn check_where_predicate( a: & $hir hir:: WherePredicate ) ;
170+ fn check_poly_trait_ref( a: & $hir hir:: PolyTraitRef , b: hir:: TraitBoundModifier ) ;
171+ fn check_fn(
172+ a: hir:: intravisit:: FnKind <$hir>,
173+ b: & $hir hir:: FnDecl ,
174+ c: & $hir hir:: Body ,
175+ d: Span ,
176+ e: ast:: NodeId ) ;
177+ fn check_fn_post(
178+ a: hir:: intravisit:: FnKind <$hir>,
179+ b: & $hir hir:: FnDecl ,
180+ c: & $hir hir:: Body ,
181+ d: Span ,
182+ e: ast:: NodeId
183+ ) ;
184+ fn check_trait_item( a: & $hir hir:: TraitItem ) ;
185+ fn check_trait_item_post( a: & $hir hir:: TraitItem ) ;
186+ fn check_impl_item( a: & $hir hir:: ImplItem ) ;
187+ fn check_impl_item_post( a: & $hir hir:: ImplItem ) ;
188+ fn check_struct_def(
189+ a: & $hir hir:: VariantData ,
190+ b: ast:: Name ,
191+ c: & $hir hir:: Generics ,
192+ d: ast:: NodeId
193+ ) ;
194+ fn check_struct_def_post(
195+ a: & $hir hir:: VariantData ,
196+ b: ast:: Name ,
197+ c: & $hir hir:: Generics ,
198+ d: ast:: NodeId
199+ ) ;
200+ fn check_struct_field( a: & $hir hir:: StructField ) ;
201+ fn check_variant( a: & $hir hir:: Variant , b: & $hir hir:: Generics ) ;
202+ fn check_variant_post( a: & $hir hir:: Variant , b: & $hir hir:: Generics ) ;
203+ fn check_lifetime( a: & $hir hir:: Lifetime ) ;
204+ fn check_path( a: & $hir hir:: Path , b: ast:: NodeId ) ;
205+ fn check_attribute( a: & $hir ast:: Attribute ) ;
206+
207+ /// Called when entering a syntax node that can have lint attributes such
208+ /// as `#[allow(...)]`. Called with *all* the attributes of that node.
209+ fn enter_lint_attrs( a: & $hir [ ast:: Attribute ] ) ;
210+
211+ /// Counterpart to `enter_lint_attrs`.
212+ fn exit_lint_attrs( a: & $hir [ ast:: Attribute ] ) ;
213+ ] ) ;
214+ )
215+ }
143216
144217/// Trait for types providing lint checks.
145218///
@@ -149,90 +222,67 @@ pub trait LintPass {
149222//
150223// FIXME: eliminate the duplication with `Visitor`. But this also
151224// contains a few lint-specific methods with no equivalent in `Visitor`.
152- pub trait LateLintPass < ' a , ' tcx > : LintPass {
153- fn check_body ( & mut self , _: & LateContext , _: & ' tcx hir:: Body ) { }
154- fn check_body_post ( & mut self , _: & LateContext , _: & ' tcx hir:: Body ) { }
155- fn check_name ( & mut self , _: & LateContext , _: Span , _: ast:: Name ) { }
156- fn check_crate ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Crate ) { }
157- fn check_crate_post ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Crate ) { }
158- fn check_mod ( & mut self ,
159- _: & LateContext < ' a , ' tcx > ,
160- _: & ' tcx hir:: Mod ,
161- _: Span ,
162- _: ast:: NodeId ) { }
163- fn check_mod_post ( & mut self ,
164- _: & LateContext < ' a , ' tcx > ,
165- _: & ' tcx hir:: Mod ,
166- _: Span ,
167- _: ast:: NodeId ) { }
168- fn check_foreign_item ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: ForeignItem ) { }
169- fn check_foreign_item_post ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: ForeignItem ) { }
170- fn check_item ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Item ) { }
171- fn check_item_post ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Item ) { }
172- fn check_local ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Local ) { }
173- fn check_block ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Block ) { }
174- fn check_block_post ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Block ) { }
175- fn check_stmt ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Stmt ) { }
176- fn check_arm ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Arm ) { }
177- fn check_pat ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Pat ) { }
178- fn check_decl ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Decl ) { }
179- fn check_expr ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Expr ) { }
180- fn check_expr_post ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Expr ) { }
181- fn check_ty ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Ty ) { }
182- fn check_generic_param ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: GenericParam ) { }
183- fn check_generics ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Generics ) { }
184- fn check_where_predicate ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: WherePredicate ) { }
185- fn check_poly_trait_ref ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: PolyTraitRef ,
186- _: hir:: TraitBoundModifier ) { }
187- fn check_fn ( & mut self ,
188- _: & LateContext < ' a , ' tcx > ,
189- _: FnKind < ' tcx > ,
190- _: & ' tcx hir:: FnDecl ,
191- _: & ' tcx hir:: Body ,
192- _: Span ,
193- _: ast:: NodeId ) { }
194- fn check_fn_post ( & mut self ,
195- _: & LateContext < ' a , ' tcx > ,
196- _: FnKind < ' tcx > ,
197- _: & ' tcx hir:: FnDecl ,
198- _: & ' tcx hir:: Body ,
199- _: Span ,
200- _: ast:: NodeId ) { }
201- fn check_trait_item ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: TraitItem ) { }
202- fn check_trait_item_post ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: TraitItem ) { }
203- fn check_impl_item ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: ImplItem ) { }
204- fn check_impl_item_post ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: ImplItem ) { }
205- fn check_struct_def ( & mut self ,
206- _: & LateContext < ' a , ' tcx > ,
207- _: & ' tcx hir:: VariantData ,
208- _: ast:: Name ,
209- _: & ' tcx hir:: Generics ,
210- _: ast:: NodeId ) { }
211- fn check_struct_def_post ( & mut self ,
212- _: & LateContext < ' a , ' tcx > ,
213- _: & ' tcx hir:: VariantData ,
214- _: ast:: Name ,
215- _: & ' tcx hir:: Generics ,
216- _: ast:: NodeId ) { }
217- fn check_struct_field ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: StructField ) { }
218- fn check_variant ( & mut self ,
219- _: & LateContext < ' a , ' tcx > ,
220- _: & ' tcx hir:: Variant ,
221- _: & ' tcx hir:: Generics ) { }
222- fn check_variant_post ( & mut self ,
223- _: & LateContext < ' a , ' tcx > ,
224- _: & ' tcx hir:: Variant ,
225- _: & ' tcx hir:: Generics ) { }
226- fn check_lifetime ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Lifetime ) { }
227- fn check_path ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx hir:: Path , _: ast:: NodeId ) { }
228- fn check_attribute ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx ast:: Attribute ) { }
229225
230- /// Called when entering a syntax node that can have lint attributes such
231- /// as `#[allow(...)]`. Called with *all* the attributes of that node.
232- fn enter_lint_attrs ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx [ ast:: Attribute ] ) { }
226+ macro_rules! expand_lint_pass_methods {
227+ ( $context: ty, [ $( $( #[ $attr: meta] ) * fn $name: ident( $( $param: ident: $arg: ty) ,* ) ; ) * ] ) => (
228+ $( #[ inline( always) ] fn $name( & mut self , $context, $( _: $arg) ,* ) { } ) *
229+ )
230+ }
233231
234- /// Counterpart to `enter_lint_attrs`.
235- fn exit_lint_attrs ( & mut self , _: & LateContext < ' a , ' tcx > , _: & ' tcx [ ast:: Attribute ] ) { }
232+ macro_rules! declare_late_lint_pass {
233+ ( [ ] , [ $hir: tt] , [ $( $methods: tt) * ] ) => (
234+ pub trait LateLintPass <' a, $hir>: LintPass {
235+ expand_lint_pass_methods!( & LateContext <' a, $hir>, [ $( $methods) * ] ) ;
236+ }
237+ )
238+ }
239+
240+ late_lint_methods ! ( declare_late_lint_pass, [ ] , [ ' tcx] ) ;
241+
242+ #[ macro_export]
243+ macro_rules! expand_combined_late_lint_pass_method {
244+ ( [ $( $passes: ident) ,* ] , $self: ident, $name: ident, $params: tt) => ( {
245+ $( $self. $passes. $name $params; ) *
246+ } )
247+ }
248+
249+ #[ macro_export]
250+ macro_rules! expand_combined_late_lint_pass_methods {
251+ ( $passes: tt, [ $( $( #[ $attr: meta] ) * fn $name: ident( $( $param: ident: $arg: ty) ,* ) ; ) * ] ) => (
252+ $( fn $name( & mut self , context: & LateContext <' a, ' tcx>, $( $param: $arg) ,* ) {
253+ expand_combined_late_lint_pass_method!( $passes, self , $name, ( context, $( $param) ,* ) ) ;
254+ } ) *
255+ )
256+ }
257+
258+ #[ macro_export]
259+ macro_rules! declare_combined_late_lint_pass {
260+ ( [ $name: ident, [ $( $passes: ident: $constructor: expr, ) * ] ] , [ $hir: tt] , $methods: tt) => (
261+ #[ allow( non_snake_case) ]
262+ struct $name {
263+ $( $passes: $passes, ) *
264+ }
265+
266+ impl $name {
267+ fn new( ) -> Self {
268+ Self {
269+ $( $passes: $constructor, ) *
270+ }
271+ }
272+ }
273+
274+ impl <' a, ' tcx> LateLintPass <' a, ' tcx> for $name {
275+ expand_combined_late_lint_pass_methods!( [ $( $passes) ,* ] , $methods) ;
276+ }
277+
278+ impl LintPass for $name {
279+ fn get_lints( & self ) -> LintArray {
280+ let mut lints = Vec :: new( ) ;
281+ $( lints. extend_from_slice( & self . $passes. get_lints( ) ) ; ) *
282+ lints
283+ }
284+ }
285+ )
236286}
237287
238288pub trait EarlyLintPass : LintPass {
0 commit comments