@@ -77,9 +77,13 @@ fn try_main() -> Result<()> {
77
77
println ! ( "{}" , flags:: RustAnalyzer :: HELP ) ;
78
78
return Ok ( ( ) ) ;
79
79
}
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
+ } ) ?;
81
86
}
82
- flags:: RustAnalyzerCmd :: ProcMacro ( flags:: ProcMacro ) => proc_macro_srv:: cli:: run ( ) ?,
83
87
flags:: RustAnalyzerCmd :: Parse ( cmd) => cmd. run ( ) ?,
84
88
flags:: RustAnalyzerCmd :: Symbols ( cmd) => cmd. run ( ) ?,
85
89
flags:: RustAnalyzerCmd :: Highlight ( cmd) => cmd. run ( ) ?,
@@ -128,6 +132,23 @@ fn setup_logging(log_file: Option<&Path>) -> Result<()> {
128
132
Ok ( ( ) )
129
133
}
130
134
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
+
131
152
fn run_server ( ) -> Result < ( ) > {
132
153
tracing:: info!( "server version {} will start" , env!( "REV" ) ) ;
133
154
0 commit comments