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,82 @@ 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 all = 0 ;
205
+ let mut fail = 0 ;
206
+ for & a in adts {
207
+ if db. generic_params ( a. into ( ) ) . iter ( ) . next ( ) . is_some ( ) {
208
+ // Data types with generics don't have layout.
209
+ continue ;
210
+ }
211
+ all += 1 ;
212
+ let Err ( e) = db. layout_of_adt ( hir_def:: AdtId :: from ( a) . into ( ) , Substitution :: empty ( Interner ) ) else {
213
+ continue ;
214
+ } ;
215
+ if verbosity. is_spammy ( ) {
216
+ let full_name = a
217
+ . module ( db)
218
+ . path_to_root ( db)
219
+ . into_iter ( )
220
+ . rev ( )
221
+ . filter_map ( |it| it. name ( db) )
222
+ . chain ( Some ( a. name ( db) ) )
223
+ . join ( "::" ) ;
224
+ println ! ( "Data layout for {full_name} failed due {e:?}" ) ;
225
+ }
226
+ fail += 1 ;
227
+ }
228
+ eprintln ! ( "Failed data layouts: {fail} ({}%)" , fail * 100 / all) ;
229
+ report_metric ( "failed data layouts" , fail, "#" ) ;
230
+ }
231
+
232
+ fn run_const_eval ( & self , db : & RootDatabase , consts : & [ hir:: Const ] , verbosity : Verbosity ) {
233
+ let mut all = 0 ;
234
+ let mut fail = 0 ;
235
+ for & c in consts {
236
+ all += 1 ;
237
+ let Err ( e) = c. render_eval ( db) else {
238
+ continue ;
239
+ } ;
240
+ if verbosity. is_spammy ( ) {
241
+ let full_name = c
242
+ . module ( db)
243
+ . path_to_root ( db)
244
+ . into_iter ( )
245
+ . rev ( )
246
+ . filter_map ( |it| it. name ( db) )
247
+ . chain ( c. name ( db) )
248
+ . join ( "::" ) ;
249
+ println ! ( "Const eval for {full_name} failed due {e:?}" ) ;
250
+ }
251
+ fail += 1 ;
252
+ }
253
+ eprintln ! ( "Failed const evals: {fail} ({}%)" , fail * 100 / all) ;
254
+ report_metric ( "failed const evals" , fail, "#" ) ;
255
+ }
256
+
257
+ fn run_mir_lowering ( & self , db : & RootDatabase , funcs : & [ Function ] , verbosity : Verbosity ) {
258
+ let all = funcs. len ( ) as u64 ;
198
259
let mut fail = 0 ;
199
- let mut h: HashMap < String , usize > = HashMap :: new ( ) ;
200
260
for f in funcs {
201
- let f = FunctionId :: from ( * f) ;
202
- let Err ( e) = db. mir_body ( f. into ( ) ) else {
261
+ let Err ( e) = db. mir_body ( FunctionId :: from ( * f) . into ( ) ) else {
203
262
continue ;
204
263
} ;
205
- let es = format ! ( "{:?}" , e) ;
206
- * h. entry ( es) . or_default ( ) += 1 ;
264
+ if verbosity. is_spammy ( ) {
265
+ let full_name = f
266
+ . module ( db)
267
+ . path_to_root ( db)
268
+ . into_iter ( )
269
+ . rev ( )
270
+ . filter_map ( |it| it. name ( db) )
271
+ . chain ( Some ( f. name ( db) ) )
272
+ . join ( "::" ) ;
273
+ println ! ( "Mir body for {full_name} failed due {e:?}" ) ;
274
+ }
207
275
fail += 1 ;
208
276
}
209
- let h = h. into_iter ( ) . sorted_by_key ( |x| x. 1 ) . collect :: < Vec < _ > > ( ) ;
210
- eprintln ! ( "Mir failed reasons: {:#?}" , h) ;
211
277
eprintln ! ( "Mir failed bodies: {fail} ({}%)" , fail * 100 / all) ;
278
+ report_metric ( "mir failed bodies" , fail, "#" ) ;
212
279
}
213
280
214
281
fn run_inference (
0 commit comments