about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs23
-rw-r--r--crates/rust-analyzer/src/cli/flags.rs3
2 files changed, 26 insertions, 0 deletions
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 @@ impl flags::AnalysisStats {
             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 @@ impl flags::AnalysisStats {
         Ok(())
     }
 
+    fn lower_mir(&self, db: &RootDatabase, funcs: &[Function]) {
+        let all = funcs.len();
+        let mut fail = 0;
+        let mut h: HashMap<String, usize> = 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::<Vec<_>>();
+        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 @@ xflags::xflags! {
             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<String>,
     pub with_deps: bool,
     pub no_sysroot: bool,