@@ -16,7 +16,11 @@ use qsc_ast::{
16
16
/// The entry point to the AST linter. It takes a [`qsc_ast::ast::Package`]
17
17
/// as input and outputs a [`Vec<Lint>`](Lint).
18
18
#[ must_use]
19
- pub fn run_ast_lints ( package : & qsc_ast:: ast:: Package , config : Option < & [ LintConfig ] > ) -> Vec < Lint > {
19
+ pub fn run_ast_lints (
20
+ package : & qsc_ast:: ast:: Package ,
21
+ config : Option < & [ LintConfig ] > ,
22
+ compilation : Compilation ,
23
+ ) -> Vec < Lint > {
20
24
let config: Vec < ( AstLint , LintLevel ) > = config
21
25
. unwrap_or ( & [ ] )
22
26
. iter ( )
@@ -29,7 +33,7 @@ pub fn run_ast_lints(package: &qsc_ast::ast::Package, config: Option<&[LintConfi
29
33
} )
30
34
. collect ( ) ;
31
35
32
- let mut lints = CombinedAstLints :: from_config ( config) ;
36
+ let mut lints = CombinedAstLints :: from_config ( config, compilation ) ;
33
37
34
38
for node in & package. nodes {
35
39
match node {
@@ -46,23 +50,71 @@ pub fn run_ast_lints(package: &qsc_ast::ast::Package, config: Option<&[LintConfi
46
50
/// The trait provides default empty implementations for the rest of the methods,
47
51
/// which will be optimized to a no-op by the rust compiler.
48
52
pub ( crate ) trait AstLintPass {
49
- fn check_attr ( & self , _attr : & Attr , _buffer : & mut Vec < Lint > ) { }
50
- fn check_block ( & self , _block : & Block , _buffer : & mut Vec < Lint > ) { }
51
- fn check_callable_decl ( & self , _callable_decl : & CallableDecl , _buffer : & mut Vec < Lint > ) { }
52
- fn check_expr ( & self , _expr : & Expr , _buffer : & mut Vec < Lint > ) { }
53
- fn check_functor_expr ( & self , _functor_expr : & FunctorExpr , _buffer : & mut Vec < Lint > ) { }
54
- fn check_ident ( & self , _ident : & Ident , _buffer : & mut Vec < Lint > ) { }
55
- fn check_item ( & self , _item : & Item , _buffer : & mut Vec < Lint > ) { }
56
- fn check_namespace ( & self , _namespace : & Namespace , _buffer : & mut Vec < Lint > ) { }
57
- fn check_package ( & self , _package : & Package , _buffer : & mut Vec < Lint > ) { }
58
- fn check_pat ( & self , _pat : & Pat , _buffer : & mut Vec < Lint > ) { }
59
- fn check_path ( & self , _path : & Path , _buffer : & mut Vec < Lint > ) { }
60
- fn check_path_kind ( & self , _path : & PathKind , _buffer : & mut Vec < Lint > ) { }
61
- fn check_qubit_init ( & self , _qubit_init : & QubitInit , _buffer : & mut Vec < Lint > ) { }
62
- fn check_spec_decl ( & self , _spec_decl : & SpecDecl , _buffer : & mut Vec < Lint > ) { }
63
- fn check_stmt ( & self , _stmt : & Stmt , _buffer : & mut Vec < Lint > ) { }
64
- fn check_ty ( & self , _ty : & Ty , _buffer : & mut Vec < Lint > ) { }
65
- fn check_ty_def ( & self , _ty_def : & TyDef , _buffer : & mut Vec < Lint > ) { }
53
+ fn check_attr ( & mut self , _attr : & Attr , _buffer : & mut Vec < Lint > , _compilation : Compilation ) { }
54
+ fn check_block ( & mut self , _block : & Block , _buffer : & mut Vec < Lint > , _compilation : Compilation ) { }
55
+ fn check_callable_decl (
56
+ & mut self ,
57
+ _callable_decl : & CallableDecl ,
58
+ _buffer : & mut Vec < Lint > ,
59
+ _compilation : Compilation ,
60
+ ) {
61
+ }
62
+ fn check_expr ( & mut self , _expr : & Expr , _buffer : & mut Vec < Lint > , _compilation : Compilation ) { }
63
+ fn check_functor_expr (
64
+ & mut self ,
65
+ _functor_expr : & FunctorExpr ,
66
+ _buffer : & mut Vec < Lint > ,
67
+ _compilation : Compilation ,
68
+ ) {
69
+ }
70
+ fn check_ident ( & mut self , _ident : & Ident , _buffer : & mut Vec < Lint > , _compilation : Compilation ) { }
71
+ fn check_item ( & mut self , _item : & Item , _buffer : & mut Vec < Lint > , _compilation : Compilation ) { }
72
+ fn check_namespace (
73
+ & mut self ,
74
+ _namespace : & Namespace ,
75
+ _buffer : & mut Vec < Lint > ,
76
+ _compilation : Compilation ,
77
+ ) {
78
+ }
79
+ fn check_package (
80
+ & mut self ,
81
+ _package : & Package ,
82
+ _buffer : & mut Vec < Lint > ,
83
+ _compilation : Compilation ,
84
+ ) {
85
+ }
86
+ fn check_pat ( & mut self , _pat : & Pat , _buffer : & mut Vec < Lint > , _compilation : Compilation ) { }
87
+ fn check_path ( & mut self , _path : & Path , _buffer : & mut Vec < Lint > , _compilation : Compilation ) { }
88
+ fn check_path_kind (
89
+ & mut self ,
90
+ _path : & PathKind ,
91
+ _buffer : & mut Vec < Lint > ,
92
+ _compilation : Compilation ,
93
+ ) {
94
+ }
95
+ fn check_qubit_init (
96
+ & mut self ,
97
+ _qubit_init : & QubitInit ,
98
+ _buffer : & mut Vec < Lint > ,
99
+ _compilation : Compilation ,
100
+ ) {
101
+ }
102
+ fn check_spec_decl (
103
+ & mut self ,
104
+ _spec_decl : & SpecDecl ,
105
+ _buffer : & mut Vec < Lint > ,
106
+ _compilation : Compilation ,
107
+ ) {
108
+ }
109
+ fn check_stmt ( & mut self , _stmt : & Stmt , _buffer : & mut Vec < Lint > , _compilation : Compilation ) { }
110
+ fn check_ty ( & mut self , _ty : & Ty , _buffer : & mut Vec < Lint > , _compilation : Compilation ) { }
111
+ fn check_ty_def (
112
+ & mut self ,
113
+ _ty_def : & TyDef ,
114
+ _buffer : & mut Vec < Lint > ,
115
+ _compilation : Compilation ,
116
+ ) {
117
+ }
66
118
}
67
119
68
120
/// This macro allow us to declare lints while avoiding boilerplate. It does three things:
@@ -82,7 +134,7 @@ macro_rules! declare_ast_lints {
82
134
// This is a silly wrapper module to avoid contaminating the environment
83
135
// calling the macro with unwanted imports.
84
136
mod _ast_macro_expansion {
85
- use crate :: { linter:: ast:: { declare_ast_lints, AstLintPass } , Lint , LintLevel } ;
137
+ use crate :: { linter:: Compilation , linter :: ast:: { declare_ast_lints, AstLintPass } , Lint , LintLevel } ;
86
138
use qsc_ast:: {
87
139
ast:: {
88
140
Attr , Block , CallableDecl , Expr , FunctorExpr , Ident , Item , Namespace , Package , Pat , Path , PathKind ,
@@ -106,25 +158,14 @@ macro_rules! declare_ast_lints {
106
158
107
159
// Declare & implement a struct representing a lint.
108
160
( @LINT_STRUCT $lint_name: ident, $default_level: expr, $msg: expr, $help: expr) => {
109
- pub ( crate ) struct $lint_name {
110
- level: LintLevel ,
111
- }
112
-
113
- impl Default for $lint_name {
114
- fn default ( ) -> Self {
115
- Self { level: Self :: DEFAULT_LEVEL }
116
- }
117
- }
118
-
119
- impl From <LintLevel > for $lint_name {
120
- fn from( value: LintLevel ) -> Self {
121
- Self { level: value }
122
- }
123
- }
124
-
125
161
impl $lint_name {
126
162
const DEFAULT_LEVEL : LintLevel = $default_level;
127
163
164
+ fn new( ) -> Self {
165
+ #[ allow( clippy:: needless_update) ]
166
+ Self { level: Self :: DEFAULT_LEVEL , ..Default :: default ( ) }
167
+ }
168
+
128
169
const fn lint_kind( & self ) -> LintKind {
129
170
LintKind :: Ast ( AstLint :: $lint_name)
130
171
}
@@ -164,24 +205,26 @@ macro_rules! declare_ast_lints {
164
205
/// Combined AST lints for speed. This combined lint allow us to
165
206
/// evaluate all the lints in a single AST pass, instead of doing
166
207
/// an individual pass for each lint in the linter.
167
- pub ( crate ) struct CombinedAstLints {
208
+ pub ( crate ) struct CombinedAstLints < ' compilation> {
168
209
pub buffer: Vec <Lint >,
210
+ pub compilation: Compilation <' compilation>,
169
211
$( $lint_name: $lint_name) ,*
170
212
}
171
213
172
- impl Default for CombinedAstLints {
173
- fn default ( ) -> Self {
214
+ impl < ' compilation> CombinedAstLints < ' compilation> {
215
+ fn new ( compilation : Compilation < ' compilation> ) -> Self {
174
216
Self {
175
- buffer: Vec :: default ( ) ,
176
- $( $lint_name: <$lint_name>:: default ( ) ) ,*
217
+ buffer: Vec :: new( ) ,
218
+ compilation,
219
+ $( $lint_name: <$lint_name>:: new( ) ) ,*
177
220
}
178
221
}
179
222
}
180
223
181
224
// Most of the calls here are empty methods and they get optimized at compile time to a no-op.
182
- impl CombinedAstLints {
183
- pub fn from_config( config: Vec <( AstLint , LintLevel ) >) -> Self {
184
- let mut combined_ast_lints = Self :: default ( ) ;
225
+ impl < ' compilation> CombinedAstLints < ' compilation> {
226
+ pub fn from_config( config: Vec <( AstLint , LintLevel ) >, compilation : Compilation < ' compilation> ) -> Self {
227
+ let mut combined_ast_lints = Self :: new ( compilation ) ;
185
228
for ( lint, level) in config {
186
229
match lint {
187
230
$( AstLint :: $lint_name => combined_ast_lints. $lint_name. level = level) ,*
@@ -190,26 +233,26 @@ macro_rules! declare_ast_lints {
190
233
combined_ast_lints
191
234
}
192
235
193
- fn check_package( & mut self , package: & Package ) { $( self . $lint_name. check_package( package, & mut self . buffer) ) ;* ; }
194
- fn check_namespace( & mut self , namespace: & Namespace ) { $( self . $lint_name. check_namespace( namespace, & mut self . buffer) ) ;* ; }
195
- fn check_item( & mut self , item: & Item ) { $( self . $lint_name. check_item( item, & mut self . buffer) ) ;* ; }
196
- fn check_attr( & mut self , attr: & Attr ) { $( self . $lint_name. check_attr( attr, & mut self . buffer) ) ;* ; }
197
- fn check_ty_def( & mut self , def: & TyDef ) { $( self . $lint_name. check_ty_def( def, & mut self . buffer) ) ;* ; }
198
- fn check_callable_decl( & mut self , decl: & CallableDecl ) { $( self . $lint_name. check_callable_decl( decl, & mut self . buffer) ) ;* ; }
199
- fn check_spec_decl( & mut self , decl: & SpecDecl ) { $( self . $lint_name. check_spec_decl( decl, & mut self . buffer) ) ;* ; }
200
- fn check_functor_expr( & mut self , expr: & FunctorExpr ) { $( self . $lint_name. check_functor_expr( expr, & mut self . buffer) ) ;* ; }
201
- fn check_ty( & mut self , ty: & Ty ) { $( self . $lint_name. check_ty( ty, & mut self . buffer) ) ;* ; }
202
- fn check_block( & mut self , block: & Block ) { $( self . $lint_name. check_block( block, & mut self . buffer) ) ;* ; }
203
- fn check_stmt( & mut self , stmt: & Stmt ) { $( self . $lint_name. check_stmt( stmt, & mut self . buffer) ) ;* ; }
204
- fn check_expr( & mut self , expr: & Expr ) { $( self . $lint_name. check_expr( expr, & mut self . buffer) ) ;* ; }
205
- fn check_pat( & mut self , pat: & Pat ) { $( self . $lint_name. check_pat( pat, & mut self . buffer) ) ;* ; }
206
- fn check_qubit_init( & mut self , init: & QubitInit ) { $( self . $lint_name. check_qubit_init( init, & mut self . buffer) ) ;* ; }
207
- fn check_path( & mut self , path: & Path ) { $( self . $lint_name. check_path( path, & mut self . buffer) ) ;* ; }
208
- fn check_path_kind( & mut self , path: & PathKind ) { $( self . $lint_name. check_path_kind( path, & mut self . buffer) ) ;* ; }
209
- fn check_ident( & mut self , ident: & Ident ) { $( self . $lint_name. check_ident( ident, & mut self . buffer) ) ;* ; }
236
+ fn check_package( & mut self , package: & Package ) { $( self . $lint_name. check_package( package, & mut self . buffer, self . compilation ) ) ;* ; }
237
+ fn check_namespace( & mut self , namespace: & Namespace ) { $( self . $lint_name. check_namespace( namespace, & mut self . buffer, self . compilation ) ) ;* ; }
238
+ fn check_item( & mut self , item: & Item ) { $( self . $lint_name. check_item( item, & mut self . buffer, self . compilation ) ) ;* ; }
239
+ fn check_attr( & mut self , attr: & Attr ) { $( self . $lint_name. check_attr( attr, & mut self . buffer, self . compilation ) ) ;* ; }
240
+ fn check_ty_def( & mut self , def: & TyDef ) { $( self . $lint_name. check_ty_def( def, & mut self . buffer, self . compilation ) ) ;* ; }
241
+ fn check_callable_decl( & mut self , decl: & CallableDecl ) { $( self . $lint_name. check_callable_decl( decl, & mut self . buffer, self . compilation ) ) ;* ; }
242
+ fn check_spec_decl( & mut self , decl: & SpecDecl ) { $( self . $lint_name. check_spec_decl( decl, & mut self . buffer, self . compilation ) ) ;* ; }
243
+ fn check_functor_expr( & mut self , expr: & FunctorExpr ) { $( self . $lint_name. check_functor_expr( expr, & mut self . buffer, self . compilation ) ) ;* ; }
244
+ fn check_ty( & mut self , ty: & Ty ) { $( self . $lint_name. check_ty( ty, & mut self . buffer, self . compilation ) ) ;* ; }
245
+ fn check_block( & mut self , block: & Block ) { $( self . $lint_name. check_block( block, & mut self . buffer, self . compilation ) ) ;* ; }
246
+ fn check_stmt( & mut self , stmt: & Stmt ) { $( self . $lint_name. check_stmt( stmt, & mut self . buffer, self . compilation ) ) ;* ; }
247
+ fn check_expr( & mut self , expr: & Expr ) { $( self . $lint_name. check_expr( expr, & mut self . buffer, self . compilation ) ) ;* ; }
248
+ fn check_pat( & mut self , pat: & Pat ) { $( self . $lint_name. check_pat( pat, & mut self . buffer, self . compilation ) ) ;* ; }
249
+ fn check_qubit_init( & mut self , init: & QubitInit ) { $( self . $lint_name. check_qubit_init( init, & mut self . buffer, self . compilation ) ) ;* ; }
250
+ fn check_path( & mut self , path: & Path ) { $( self . $lint_name. check_path( path, & mut self . buffer, self . compilation ) ) ;* ; }
251
+ fn check_path_kind( & mut self , path: & PathKind ) { $( self . $lint_name. check_path_kind( path, & mut self . buffer, self . compilation ) ) ;* ; }
252
+ fn check_ident( & mut self , ident: & Ident ) { $( self . $lint_name. check_ident( ident, & mut self . buffer, self . compilation ) ) ;* ; }
210
253
}
211
254
212
- impl <' a> Visitor <' a> for CombinedAstLints {
255
+ impl <' a> Visitor <' a> for CombinedAstLints < ' _> {
213
256
fn visit_package( & mut self , package: & ' a Package ) {
214
257
self . check_package( package) ;
215
258
visit:: walk_package( self , package) ;
@@ -299,4 +342,4 @@ macro_rules! declare_ast_lints {
299
342
300
343
pub ( crate ) use declare_ast_lints;
301
344
302
- use super :: LintKind ;
345
+ use super :: { Compilation , LintKind } ;
0 commit comments