@@ -29,7 +29,6 @@ use profile::{Bytes, StopWatch};
2929use project_model:: { CargoConfig , ProjectManifest , ProjectWorkspace , RustLibSource } ;
3030use rayon:: prelude:: * ;
3131use rustc_hash:: FxHashSet ;
32- use stdx:: format_to;
3332use syntax:: { AstNode , SyntaxNode } ;
3433use vfs:: { AbsPathBuf , Vfs , VfsPath } ;
3534
@@ -176,8 +175,11 @@ impl flags::AnalysisStats {
176175 shuffle ( & mut rng, & mut bodies) ;
177176 }
178177
178+ if !self . skip_lowering {
179+ self . run_body_lowering ( db, & vfs, & bodies, verbosity) ;
180+ }
181+
179182 if !self . skip_inference {
180- // FIXME: Consider running inference on all body kinds?
181183 self . run_inference ( db, & vfs, & bodies, verbosity) ;
182184 }
183185
@@ -238,8 +240,10 @@ impl flags::AnalysisStats {
238240 continue ;
239241 }
240242 all += 1 ;
241- let Err ( e) = db. layout_of_adt ( hir_def:: AdtId :: from ( a) . into ( ) , Substitution :: empty ( Interner ) , a. krate ( db) . into ( ) ) else {
242- continue ;
243+ let Err ( e)
244+ = db. layout_of_adt ( hir_def:: AdtId :: from ( a) . into ( ) , Substitution :: empty ( Interner ) , a. krate ( db) . into ( ) )
245+ else {
246+ continue
243247 } ;
244248 if verbosity. is_spammy ( ) {
245249 let full_name = a
@@ -255,9 +259,11 @@ impl flags::AnalysisStats {
255259 }
256260 fail += 1 ;
257261 }
258- eprintln ! ( "{:<20} {}" , "Data layouts:" , sw. elapsed( ) ) ;
262+ let data_layout_time = sw. elapsed ( ) ;
263+ eprintln ! ( "{:<20} {}" , "Data layouts:" , data_layout_time) ;
259264 eprintln ! ( "Failed data layouts: {fail} ({}%)" , percentage( fail, all) ) ;
260265 report_metric ( "failed data layouts" , fail, "#" ) ;
266+ report_metric ( "data layout time" , data_layout_time. time . as_millis ( ) as u64 , "ms" ) ;
261267 }
262268
263269 fn run_const_eval ( & self , db : & RootDatabase , consts : & [ hir:: Const ] , verbosity : Verbosity ) {
@@ -283,9 +289,11 @@ impl flags::AnalysisStats {
283289 }
284290 fail += 1 ;
285291 }
286- eprintln ! ( "{:<20} {}" , "Const evaluation:" , sw. elapsed( ) ) ;
292+ let const_eval_time = sw. elapsed ( ) ;
293+ eprintln ! ( "{:<20} {}" , "Const evaluation:" , const_eval_time) ;
287294 eprintln ! ( "Failed const evals: {fail} ({}%)" , percentage( fail, all) ) ;
288295 report_metric ( "failed const evals" , fail, "#" ) ;
296+ report_metric ( "const eval time" , const_eval_time. time . as_millis ( ) as u64 , "ms" ) ;
289297 }
290298
291299 fn run_mir_lowering ( & self , db : & RootDatabase , bodies : & [ DefWithBody ] , verbosity : Verbosity ) {
@@ -310,9 +318,11 @@ impl flags::AnalysisStats {
310318 }
311319 fail += 1 ;
312320 }
313- eprintln ! ( "{:<20} {}" , "MIR lowering:" , sw. elapsed( ) ) ;
321+ let mir_lowering_time = sw. elapsed ( ) ;
322+ eprintln ! ( "{:<20} {}" , "MIR lowering:" , mir_lowering_time) ;
314323 eprintln ! ( "Mir failed bodies: {fail} ({}%)" , percentage( fail, all) ) ;
315324 report_metric ( "mir failed bodies" , fail, "#" ) ;
325+ report_metric ( "mir lowering time" , mir_lowering_time. time . as_millis ( ) as u64 , "ms" ) ;
316326 }
317327
318328 fn run_inference (
@@ -354,7 +364,7 @@ impl flags::AnalysisStats {
354364 for & body_id in bodies {
355365 let name = body_id. name ( db) . unwrap_or_else ( Name :: missing) ;
356366 let module = body_id. module ( db) ;
357- let full_name = || {
367+ let full_name = move || {
358368 module
359369 . krate ( )
360370 . display_name ( db)
@@ -366,7 +376,7 @@ impl flags::AnalysisStats {
366376 . into_iter ( )
367377 . filter_map ( |it| it. name ( db) )
368378 . rev ( )
369- . chain ( Some ( name. clone ( ) ) )
379+ . chain ( Some ( body_id . name ( db ) . unwrap_or_else ( Name :: missing ) ) )
370380 . map ( |it| it. display ( db) . to_string ( ) ) ,
371381 )
372382 . join ( "::" )
@@ -376,26 +386,31 @@ impl flags::AnalysisStats {
376386 continue ;
377387 }
378388 }
379- let mut msg = format ! ( "processing: {}" , full_name( ) ) ;
380- if verbosity. is_verbose ( ) {
381- let source = match body_id {
382- DefWithBody :: Function ( it) => it. source ( db) . map ( |it| it. syntax ( ) . cloned ( ) ) ,
383- DefWithBody :: Static ( it) => it. source ( db) . map ( |it| it. syntax ( ) . cloned ( ) ) ,
384- DefWithBody :: Const ( it) => it. source ( db) . map ( |it| it. syntax ( ) . cloned ( ) ) ,
385- DefWithBody :: Variant ( it) => it. source ( db) . map ( |it| it. syntax ( ) . cloned ( ) ) ,
386- DefWithBody :: InTypeConst ( _) => unimplemented ! ( ) ,
387- } ;
388- if let Some ( src) = source {
389- let original_file = src. file_id . original_file ( db) ;
390- let path = vfs. file_path ( original_file) ;
391- let syntax_range = src. value . text_range ( ) ;
392- format_to ! ( msg, " ({} {:?})" , path, syntax_range) ;
389+ let msg = move || {
390+ if verbosity. is_verbose ( ) {
391+ let source = match body_id {
392+ DefWithBody :: Function ( it) => it. source ( db) . map ( |it| it. syntax ( ) . cloned ( ) ) ,
393+ DefWithBody :: Static ( it) => it. source ( db) . map ( |it| it. syntax ( ) . cloned ( ) ) ,
394+ DefWithBody :: Const ( it) => it. source ( db) . map ( |it| it. syntax ( ) . cloned ( ) ) ,
395+ DefWithBody :: Variant ( it) => it. source ( db) . map ( |it| it. syntax ( ) . cloned ( ) ) ,
396+ DefWithBody :: InTypeConst ( _) => unimplemented ! ( ) ,
397+ } ;
398+ if let Some ( src) = source {
399+ let original_file = src. file_id . original_file ( db) ;
400+ let path = vfs. file_path ( original_file) ;
401+ let syntax_range = src. value . text_range ( ) ;
402+ format ! ( "processing: {} ({} {:?})" , full_name( ) , path, syntax_range)
403+ } else {
404+ format ! ( "processing: {}" , full_name( ) )
405+ }
406+ } else {
407+ format ! ( "processing: {}" , full_name( ) )
393408 }
394- }
409+ } ;
395410 if verbosity. is_spammy ( ) {
396- bar. println ( msg. to_string ( ) ) ;
411+ bar. println ( msg ( ) ) ;
397412 }
398- bar. set_message ( & msg) ;
413+ bar. set_message ( msg) ;
399414 let ( body, sm) = db. body_with_source_map ( body_id. into ( ) ) ;
400415 let inference_result = db. infer ( body_id. into ( ) ) ;
401416
@@ -596,6 +611,7 @@ impl flags::AnalysisStats {
596611 }
597612
598613 bar. finish_and_clear ( ) ;
614+ let inference_time = inference_sw. elapsed ( ) ;
599615 eprintln ! (
600616 " exprs: {}, ??ty: {} ({}%), ?ty: {} ({}%), !ty: {}" ,
601617 num_exprs,
@@ -614,12 +630,89 @@ impl flags::AnalysisStats {
614630 percentage( num_pats_partially_unknown, num_pats) ,
615631 num_pat_type_mismatches
616632 ) ;
633+ eprintln ! ( "{:<20} {}" , "Inference:" , inference_time) ;
617634 report_metric ( "unknown type" , num_exprs_unknown, "#" ) ;
618635 report_metric ( "type mismatches" , num_expr_type_mismatches, "#" ) ;
619636 report_metric ( "pattern unknown type" , num_pats_unknown, "#" ) ;
620637 report_metric ( "pattern type mismatches" , num_pat_type_mismatches, "#" ) ;
638+ report_metric ( "inference time" , inference_time. time . as_millis ( ) as u64 , "ms" ) ;
639+ }
621640
622- eprintln ! ( "{:<20} {}" , "Inference:" , inference_sw. elapsed( ) ) ;
641+ fn run_body_lowering (
642+ & self ,
643+ db : & RootDatabase ,
644+ vfs : & Vfs ,
645+ bodies : & [ DefWithBody ] ,
646+ verbosity : Verbosity ,
647+ ) {
648+ let mut bar = match verbosity {
649+ Verbosity :: Quiet | Verbosity :: Spammy => ProgressReport :: hidden ( ) ,
650+ _ if self . output . is_some ( ) => ProgressReport :: hidden ( ) ,
651+ _ => ProgressReport :: new ( bodies. len ( ) as u64 ) ,
652+ } ;
653+
654+ let mut sw = self . stop_watch ( ) ;
655+ bar. tick ( ) ;
656+ for & body_id in bodies {
657+ let module = body_id. module ( db) ;
658+ let full_name = move || {
659+ module
660+ . krate ( )
661+ . display_name ( db)
662+ . map ( |it| it. canonical_name ( ) . to_string ( ) )
663+ . into_iter ( )
664+ . chain (
665+ module
666+ . path_to_root ( db)
667+ . into_iter ( )
668+ . filter_map ( |it| it. name ( db) )
669+ . rev ( )
670+ . chain ( Some ( body_id. name ( db) . unwrap_or_else ( Name :: missing) ) )
671+ . map ( |it| it. display ( db) . to_string ( ) ) ,
672+ )
673+ . join ( "::" )
674+ } ;
675+ if let Some ( only_name) = self . only . as_deref ( ) {
676+ if body_id. name ( db) . unwrap_or_else ( Name :: missing) . display ( db) . to_string ( )
677+ != only_name
678+ && full_name ( ) != only_name
679+ {
680+ continue ;
681+ }
682+ }
683+ let msg = move || {
684+ if verbosity. is_verbose ( ) {
685+ let source = match body_id {
686+ DefWithBody :: Function ( it) => it. source ( db) . map ( |it| it. syntax ( ) . cloned ( ) ) ,
687+ DefWithBody :: Static ( it) => it. source ( db) . map ( |it| it. syntax ( ) . cloned ( ) ) ,
688+ DefWithBody :: Const ( it) => it. source ( db) . map ( |it| it. syntax ( ) . cloned ( ) ) ,
689+ DefWithBody :: Variant ( it) => it. source ( db) . map ( |it| it. syntax ( ) . cloned ( ) ) ,
690+ DefWithBody :: InTypeConst ( _) => unimplemented ! ( ) ,
691+ } ;
692+ if let Some ( src) = source {
693+ let original_file = src. file_id . original_file ( db) ;
694+ let path = vfs. file_path ( original_file) ;
695+ let syntax_range = src. value . text_range ( ) ;
696+ format ! ( "processing: {} ({} {:?})" , full_name( ) , path, syntax_range)
697+ } else {
698+ format ! ( "processing: {}" , full_name( ) )
699+ }
700+ } else {
701+ format ! ( "processing: {}" , full_name( ) )
702+ }
703+ } ;
704+ if verbosity. is_spammy ( ) {
705+ bar. println ( msg ( ) ) ;
706+ }
707+ bar. set_message ( msg) ;
708+ db. body_with_source_map ( body_id. into ( ) ) ;
709+ bar. inc ( 1 ) ;
710+ }
711+
712+ bar. finish_and_clear ( ) ;
713+ let body_lowering_time = sw. elapsed ( ) ;
714+ eprintln ! ( "{:<20} {}" , "Body lowering:" , body_lowering_time) ;
715+ report_metric ( "body lowering time" , body_lowering_time. time . as_millis ( ) as u64 , "ms" ) ;
623716 }
624717
625718 fn stop_watch ( & self ) -> StopWatch {
0 commit comments