@@ -77,9 +77,13 @@ fn try_main() -> Result<()> {
7777 println ! ( "{}" , flags:: RustAnalyzer :: HELP ) ;
7878 return Ok ( ( ) ) ;
7979 }
80- run_server ( ) ?
80+ with_extra_thread ( "rust-analyzer server thread" , run_server) ?;
81+ }
82+ flags:: RustAnalyzerCmd :: ProcMacro ( flags:: ProcMacro ) => {
83+ with_extra_thread ( "rust-analyzer proc-macro expander" , || {
84+ proc_macro_srv:: cli:: run ( ) . map_err ( Into :: into)
85+ } ) ?;
8186 }
82- flags:: RustAnalyzerCmd :: ProcMacro ( flags:: ProcMacro ) => proc_macro_srv:: cli:: run ( ) ?,
8387 flags:: RustAnalyzerCmd :: Parse ( cmd) => cmd. run ( ) ?,
8488 flags:: RustAnalyzerCmd :: Symbols ( cmd) => cmd. run ( ) ?,
8589 flags:: RustAnalyzerCmd :: Highlight ( cmd) => cmd. run ( ) ?,
@@ -128,6 +132,23 @@ fn setup_logging(log_file: Option<&Path>) -> Result<()> {
128132 Ok ( ( ) )
129133}
130134
135+ const STACK_SIZE : usize = 1024 * 1024 * 8 ;
136+
137+ /// Parts of rust-analyzer can use a lot of stack space, and some operating systems only give us
138+ /// 1 MB by default (eg. Windows), so this spawns a new thread with hopefully sufficient stack
139+ /// space.
140+ fn with_extra_thread (
141+ thread_name : impl Into < String > ,
142+ f : impl FnOnce ( ) -> Result < ( ) > + Send + ' static ,
143+ ) -> Result < ( ) > {
144+ let handle =
145+ std:: thread:: Builder :: new ( ) . name ( thread_name. into ( ) ) . stack_size ( STACK_SIZE ) . spawn ( f) ?;
146+ match handle. join ( ) {
147+ Ok ( res) => res,
148+ Err ( panic) => std:: panic:: resume_unwind ( panic) ,
149+ }
150+ }
151+
131152fn run_server ( ) -> Result < ( ) > {
132153 tracing:: info!( "server version {} will start" , env!( "REV" ) ) ;
133154
0 commit comments