2
2
//! errors.
3
3
4
4
use std:: {
5
- collections:: HashMap ,
6
5
env,
7
6
time:: { SystemTime , UNIX_EPOCH } ,
8
7
} ;
@@ -16,7 +15,7 @@ use hir_def::{
16
15
hir:: { ExprId , PatId } ,
17
16
FunctionId ,
18
17
} ;
19
- use hir_ty:: { Interner , TyExt , TypeFlags } ;
18
+ use hir_ty:: { Interner , Substitution , TyExt , TypeFlags } ;
20
19
use ide:: { Analysis , AnalysisHost , LineCol , RootDatabase } ;
21
20
use ide_db:: base_db:: {
22
21
salsa:: { self , debug:: DebugQueryTable , ParallelDatabase } ,
@@ -122,14 +121,19 @@ impl flags::AnalysisStats {
122
121
eprint ! ( " crates: {num_crates}" ) ;
123
122
let mut num_decls = 0 ;
124
123
let mut funcs = Vec :: new ( ) ;
124
+ let mut adts = Vec :: new ( ) ;
125
+ let mut consts = Vec :: new ( ) ;
125
126
while let Some ( module) = visit_queue. pop ( ) {
126
127
if visited_modules. insert ( module) {
127
128
visit_queue. extend ( module. children ( db) ) ;
128
129
129
130
for decl in module. declarations ( db) {
130
131
num_decls += 1 ;
131
- if let ModuleDef :: Function ( f) = decl {
132
- funcs. push ( f) ;
132
+ match decl {
133
+ ModuleDef :: Function ( f) => funcs. push ( f) ,
134
+ ModuleDef :: Adt ( a) => adts. push ( a) ,
135
+ ModuleDef :: Const ( c) => consts. push ( c) ,
136
+ _ => ( ) ,
133
137
}
134
138
}
135
139
@@ -154,10 +158,13 @@ impl flags::AnalysisStats {
154
158
self . run_inference ( & host, db, & vfs, & funcs, verbosity) ;
155
159
}
156
160
157
- if self . mir_stats {
158
- self . lower_mir ( db, & funcs) ;
161
+ if ! self . skip_mir_stats {
162
+ self . run_mir_lowering ( db, & funcs, verbosity ) ;
159
163
}
160
164
165
+ self . run_data_layout ( db, & adts, verbosity) ;
166
+ self . run_const_eval ( db, & consts, verbosity) ;
167
+
161
168
let total_span = analysis_sw. elapsed ( ) ;
162
169
eprintln ! ( "{:<20} {total_span}" , "Total:" ) ;
163
170
report_metric ( "total time" , total_span. time . as_millis ( ) as u64 , "ms" ) ;
@@ -193,22 +200,88 @@ impl flags::AnalysisStats {
193
200
Ok ( ( ) )
194
201
}
195
202
196
- fn lower_mir ( & self , db : & RootDatabase , funcs : & [ Function ] ) {
197
- let all = funcs. len ( ) ;
203
+ fn run_data_layout ( & self , db : & RootDatabase , adts : & [ hir:: Adt ] , verbosity : Verbosity ) {
204
+ let mut sw = self . stop_watch ( ) ;
205
+ let mut all = 0 ;
206
+ let mut fail = 0 ;
207
+ for & a in adts {
208
+ if db. generic_params ( a. into ( ) ) . iter ( ) . next ( ) . is_some ( ) {
209
+ // Data types with generics don't have layout.
210
+ continue ;
211
+ }
212
+ all += 1 ;
213
+ let Err ( e) = db. layout_of_adt ( hir_def:: AdtId :: from ( a) . into ( ) , Substitution :: empty ( Interner ) ) else {
214
+ continue ;
215
+ } ;
216
+ if verbosity. is_spammy ( ) {
217
+ let full_name = a
218
+ . module ( db)
219
+ . path_to_root ( db)
220
+ . into_iter ( )
221
+ . rev ( )
222
+ . filter_map ( |it| it. name ( db) )
223
+ . chain ( Some ( a. name ( db) ) )
224
+ . join ( "::" ) ;
225
+ println ! ( "Data layout for {full_name} failed due {e:?}" ) ;
226
+ }
227
+ fail += 1 ;
228
+ }
229
+ eprintln ! ( "{:<20} {}" , "Data layouts:" , sw. elapsed( ) ) ;
230
+ eprintln ! ( "Failed data layouts: {fail} ({}%)" , fail * 100 / all) ;
231
+ report_metric ( "failed data layouts" , fail, "#" ) ;
232
+ }
233
+
234
+ fn run_const_eval ( & self , db : & RootDatabase , consts : & [ hir:: Const ] , verbosity : Verbosity ) {
235
+ let mut sw = self . stop_watch ( ) ;
236
+ let mut all = 0 ;
237
+ let mut fail = 0 ;
238
+ for & c in consts {
239
+ all += 1 ;
240
+ let Err ( e) = c. render_eval ( db) else {
241
+ continue ;
242
+ } ;
243
+ if verbosity. is_spammy ( ) {
244
+ let full_name = c
245
+ . module ( db)
246
+ . path_to_root ( db)
247
+ . into_iter ( )
248
+ . rev ( )
249
+ . filter_map ( |it| it. name ( db) )
250
+ . chain ( c. name ( db) )
251
+ . join ( "::" ) ;
252
+ println ! ( "Const eval for {full_name} failed due {e:?}" ) ;
253
+ }
254
+ fail += 1 ;
255
+ }
256
+ eprintln ! ( "{:<20} {}" , "Const evaluation:" , sw. elapsed( ) ) ;
257
+ eprintln ! ( "Failed const evals: {fail} ({}%)" , fail * 100 / all) ;
258
+ report_metric ( "failed const evals" , fail, "#" ) ;
259
+ }
260
+
261
+ fn run_mir_lowering ( & self , db : & RootDatabase , funcs : & [ Function ] , verbosity : Verbosity ) {
262
+ let mut sw = self . stop_watch ( ) ;
263
+ let all = funcs. len ( ) as u64 ;
198
264
let mut fail = 0 ;
199
- let mut h: HashMap < String , usize > = HashMap :: new ( ) ;
200
265
for f in funcs {
201
- let f = FunctionId :: from ( * f) ;
202
- let Err ( e) = db. mir_body ( f. into ( ) ) else {
266
+ let Err ( e) = db. mir_body ( FunctionId :: from ( * f) . into ( ) ) else {
203
267
continue ;
204
268
} ;
205
- let es = format ! ( "{:?}" , e) ;
206
- * h. entry ( es) . or_default ( ) += 1 ;
269
+ if verbosity. is_spammy ( ) {
270
+ let full_name = f
271
+ . module ( db)
272
+ . path_to_root ( db)
273
+ . into_iter ( )
274
+ . rev ( )
275
+ . filter_map ( |it| it. name ( db) )
276
+ . chain ( Some ( f. name ( db) ) )
277
+ . join ( "::" ) ;
278
+ println ! ( "Mir body for {full_name} failed due {e:?}" ) ;
279
+ }
207
280
fail += 1 ;
208
281
}
209
- let h = h. into_iter ( ) . sorted_by_key ( |x| x. 1 ) . collect :: < Vec < _ > > ( ) ;
210
- eprintln ! ( "Mir failed reasons: {:#?}" , h) ;
282
+ eprintln ! ( "{:<20} {}" , "MIR lowering:" , sw. elapsed( ) ) ;
211
283
eprintln ! ( "Mir failed bodies: {fail} ({}%)" , fail * 100 / all) ;
284
+ report_metric ( "mir failed bodies" , fail, "#" ) ;
212
285
}
213
286
214
287
fn run_inference (
0 commit comments