diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index 6ce1de5d32b..e1504743bfd 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -2,6 +2,7 @@ //! errors. use std::{ + collections::HashMap, env, time::{SystemTime, UNIX_EPOCH}, }; @@ -153,6 +154,10 @@ pub fn run(self, verbosity: Verbosity) -> Result<()> { self.run_inference(&host, db, &vfs, &funcs, verbosity); } + if self.mir_stats { + self.lower_mir(db, &funcs); + } + let total_span = analysis_sw.elapsed(); eprintln!("{:<20} {total_span}", "Total:"); report_metric("total time", total_span.time.as_millis() as u64, "ms"); @@ -189,6 +194,24 @@ pub fn run(self, verbosity: Verbosity) -> Result<()> { Ok(()) } + fn lower_mir(&self, db: &RootDatabase, funcs: &[Function]) { + let all = funcs.len(); + let mut fail = 0; + let mut h: HashMap = HashMap::new(); + for f in funcs { + let f = FunctionId::from(*f); + let Err(e) = db.mir_body(f.into()) else { + continue; + }; + let es = format!("{:?}", e); + *h.entry(es).or_default() += 1; + fail += 1; + } + let h = h.into_iter().sorted_by_key(|x| x.1).collect::>(); + eprintln!("Mir failed reasons: {:#?}", h); + eprintln!("Mir failed bodies: {fail} ({}%)", fail * 100 / all); + } + fn run_inference( &self, host: &AnalysisHost, diff --git a/crates/rust-analyzer/src/cli/flags.rs b/crates/rust-analyzer/src/cli/flags.rs index 770612cc947..b085a0a892a 100644 --- a/crates/rust-analyzer/src/cli/flags.rs +++ b/crates/rust-analyzer/src/cli/flags.rs @@ -66,6 +66,8 @@ optional --memory-usage /// Print the total length of all source and macro files (whitespace is not counted). optional --source-stats + /// Print the number of bodies that fail to lower to mir, in addition to failed reasons. + optional --mir-stats /// Only analyze items matching this path. optional -o, --only path: String @@ -172,6 +174,7 @@ pub struct AnalysisStats { pub parallel: bool, pub memory_usage: bool, pub source_stats: bool, + pub mir_stats: bool, pub only: Option, pub with_deps: bool, pub no_sysroot: bool,