about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/rust-analyzer/src/bin/main.rs25
1 files changed, 23 insertions, 2 deletions
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index 15ae0e64806..df61ba8eec8 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -77,9 +77,13 @@ fn try_main() -> Result<()> {
                 println!("{}", flags::RustAnalyzer::HELP);
                 return Ok(());
             }
-            run_server()?
+            with_extra_thread("rust-analyzer server thread", run_server)?;
+        }
+        flags::RustAnalyzerCmd::ProcMacro(flags::ProcMacro) => {
+            with_extra_thread("rust-analyzer proc-macro expander", || {
+                proc_macro_srv::cli::run().map_err(Into::into)
+            })?;
         }
-        flags::RustAnalyzerCmd::ProcMacro(flags::ProcMacro) => proc_macro_srv::cli::run()?,
         flags::RustAnalyzerCmd::Parse(cmd) => cmd.run()?,
         flags::RustAnalyzerCmd::Symbols(cmd) => cmd.run()?,
         flags::RustAnalyzerCmd::Highlight(cmd) => cmd.run()?,
@@ -128,6 +132,23 @@ fn setup_logging(log_file: Option<&Path>) -> Result<()> {
     Ok(())
 }
 
+const STACK_SIZE: usize = 1024 * 1024 * 8;
+
+/// Parts of rust-analyzer can use a lot of stack space, and some operating systems only give us
+/// 1 MB by default (eg. Windows), so this spawns a new thread with hopefully sufficient stack
+/// space.
+fn with_extra_thread(
+    thread_name: impl Into<String>,
+    f: impl FnOnce() -> Result<()> + Send + 'static,
+) -> Result<()> {
+    let handle =
+        std::thread::Builder::new().name(thread_name.into()).stack_size(STACK_SIZE).spawn(f)?;
+    match handle.join() {
+        Ok(res) => res,
+        Err(panic) => std::panic::resume_unwind(panic),
+    }
+}
+
 fn run_server() -> Result<()> {
     tracing::info!("server version {} will start", env!("REV"));