Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 8c526ee

Browse files
committed
Move interior mutability into ProcMacroSrvProcess
1 parent fd9dce7 commit 8c526ee

File tree

2 files changed

+31
-43
lines changed

2 files changed

+31
-43
lines changed

src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@ use indexmap::IndexSet;
1515
use paths::{AbsPath, AbsPathBuf};
1616
use rustc_hash::FxHashMap;
1717
use span::Span;
18-
use std::{
19-
fmt, io,
20-
sync::{Arc, Mutex},
21-
};
18+
use std::{fmt, io, sync::Arc};
19+
use tt::SmolStr;
2220

2321
use serde::{Deserialize, Serialize};
2422

@@ -48,9 +46,7 @@ pub struct ProcMacroServer {
4846
///
4947
/// That means that concurrent salsa requests may block each other when expanding proc macros,
5048
/// which is unfortunate, but simple and good enough for the time being.
51-
///
52-
/// Therefore, we just wrap the `ProcMacroProcessSrv` in a mutex here.
53-
process: Arc<Mutex<ProcMacroProcessSrv>>,
49+
process: Arc<ProcMacroProcessSrv>,
5450
path: AbsPathBuf,
5551
}
5652

@@ -70,9 +66,9 @@ impl MacroDylib {
7066
/// we share a single expander process for all macros.
7167
#[derive(Debug, Clone)]
7268
pub struct ProcMacro {
73-
process: Arc<Mutex<ProcMacroProcessSrv>>,
69+
process: Arc<ProcMacroProcessSrv>,
7470
dylib_path: AbsPathBuf,
75-
name: String,
71+
name: SmolStr,
7672
kind: ProcMacroKind,
7773
}
7874

@@ -89,7 +85,6 @@ impl PartialEq for ProcMacro {
8985
#[derive(Clone, Debug)]
9086
pub struct ServerError {
9187
pub message: String,
92-
// io::Error isn't Clone for some reason
9388
pub io: Option<Arc<io::Error>>,
9489
}
9590

@@ -104,21 +99,14 @@ impl fmt::Display for ServerError {
10499
}
105100
}
106101

107-
pub struct MacroPanic {
108-
pub message: String,
109-
}
110-
111102
impl ProcMacroServer {
112103
/// Spawns an external process as the proc macro server and returns a client connected to it.
113104
pub fn spawn(
114105
process_path: &AbsPath,
115106
env: &FxHashMap<String, String>,
116107
) -> io::Result<ProcMacroServer> {
117108
let process = ProcMacroProcessSrv::run(process_path, env)?;
118-
Ok(ProcMacroServer {
119-
process: Arc::new(Mutex::new(process)),
120-
path: process_path.to_owned(),
121-
})
109+
Ok(ProcMacroServer { process: Arc::new(process), path: process_path.to_owned() })
122110
}
123111

124112
pub fn path(&self) -> &AbsPath {
@@ -127,15 +115,14 @@ impl ProcMacroServer {
127115

128116
pub fn load_dylib(&self, dylib: MacroDylib) -> Result<Vec<ProcMacro>, ServerError> {
129117
let _p = tracing::info_span!("ProcMacroServer::load_dylib").entered();
130-
let macros =
131-
self.process.lock().unwrap_or_else(|e| e.into_inner()).find_proc_macros(&dylib.path)?;
118+
let macros = self.process.find_proc_macros(&dylib.path)?;
132119

133120
match macros {
134121
Ok(macros) => Ok(macros
135122
.into_iter()
136123
.map(|(name, kind)| ProcMacro {
137124
process: self.process.clone(),
138-
name,
125+
name: name.into(),
139126
kind,
140127
dylib_path: dylib.path.clone(),
141128
})
@@ -163,7 +150,7 @@ impl ProcMacro {
163150
call_site: Span,
164151
mixed_site: Span,
165152
) -> Result<Result<tt::Subtree<Span>, PanicMessage>, ServerError> {
166-
let version = self.process.lock().unwrap_or_else(|e| e.into_inner()).version();
153+
let version = self.process.version();
167154
let current_dir = env.get("CARGO_MANIFEST_DIR");
168155

169156
let mut span_data_table = IndexSet::default();
@@ -190,11 +177,7 @@ impl ProcMacro {
190177
},
191178
};
192179

193-
let response = self
194-
.process
195-
.lock()
196-
.unwrap_or_else(|e| e.into_inner())
197-
.send_task(msg::Request::ExpandMacro(Box::new(task)))?;
180+
let response = self.process.send_task(msg::Request::ExpandMacro(Box::new(task)))?;
198181

199182
match response {
200183
msg::Response::ExpandMacro(it) => {

src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::{
44
io::{self, BufRead, BufReader, Read, Write},
55
process::{Child, ChildStdin, ChildStdout, Command, Stdio},
6-
sync::Arc,
6+
sync::{Arc, Mutex},
77
};
88

99
use paths::AbsPath;
@@ -17,13 +17,20 @@ use crate::{
1717

1818
#[derive(Debug)]
1919
pub(crate) struct ProcMacroProcessSrv {
20+
/// The state of the proc-macro server process, the protocol is currently strictly sequential
21+
/// hence the lock on the state.
22+
state: Mutex<ProcessSrvState>,
23+
version: u32,
24+
mode: SpanMode,
25+
}
26+
27+
#[derive(Debug)]
28+
struct ProcessSrvState {
2029
process: Process,
2130
stdin: ChildStdin,
2231
stdout: BufReader<ChildStdout>,
2332
/// Populated when the server exits.
2433
server_exited: Option<ServerError>,
25-
version: u32,
26-
mode: SpanMode,
2734
}
2835

2936
impl ProcMacroProcessSrv {
@@ -36,10 +43,7 @@ impl ProcMacroProcessSrv {
3643
let (stdin, stdout) = process.stdio().expect("couldn't access child stdio");
3744

3845
io::Result::Ok(ProcMacroProcessSrv {
39-
process,
40-
stdin,
41-
stdout,
42-
server_exited: None,
46+
state: Mutex::new(ProcessSrvState { process, stdin, stdout, server_exited: None }),
4347
version: 0,
4448
mode: SpanMode::Id,
4549
})
@@ -76,7 +80,7 @@ impl ProcMacroProcessSrv {
7680
self.version
7781
}
7882

79-
pub(crate) fn version_check(&mut self) -> Result<u32, ServerError> {
83+
fn version_check(&self) -> Result<u32, ServerError> {
8084
let request = Request::ApiVersionCheck {};
8185
let response = self.send_task(request)?;
8286

@@ -86,7 +90,7 @@ impl ProcMacroProcessSrv {
8690
}
8791
}
8892

89-
fn enable_rust_analyzer_spans(&mut self) -> Result<SpanMode, ServerError> {
93+
fn enable_rust_analyzer_spans(&self) -> Result<SpanMode, ServerError> {
9094
let request = Request::SetConfig(crate::msg::ServerConfig {
9195
span_mode: crate::msg::SpanMode::RustAnalyzer,
9296
});
@@ -99,7 +103,7 @@ impl ProcMacroProcessSrv {
99103
}
100104

101105
pub(crate) fn find_proc_macros(
102-
&mut self,
106+
&self,
103107
dylib_path: &AbsPath,
104108
) -> Result<Result<Vec<(String, ProcMacroKind)>, String>, ServerError> {
105109
let request = Request::ListMacros { dylib_path: dylib_path.to_path_buf().into() };
@@ -112,28 +116,29 @@ impl ProcMacroProcessSrv {
112116
}
113117
}
114118

115-
pub(crate) fn send_task(&mut self, req: Request) -> Result<Response, ServerError> {
116-
if let Some(server_error) = &self.server_exited {
119+
pub(crate) fn send_task(&self, req: Request) -> Result<Response, ServerError> {
120+
let state = &mut *self.state.lock().unwrap();
121+
if let Some(server_error) = &state.server_exited {
117122
return Err(server_error.clone());
118123
}
119124

120125
let mut buf = String::new();
121-
send_request(&mut self.stdin, &mut self.stdout, req, &mut buf).map_err(|e| {
126+
send_request(&mut state.stdin, &mut state.stdout, req, &mut buf).map_err(|e| {
122127
if e.io.as_ref().map(|it| it.kind()) == Some(io::ErrorKind::BrokenPipe) {
123-
match self.process.child.try_wait() {
128+
match state.process.child.try_wait() {
124129
Ok(None) => e,
125130
Ok(Some(status)) => {
126131
let mut msg = String::new();
127132
if !status.success() {
128-
if let Some(stderr) = self.process.child.stderr.as_mut() {
133+
if let Some(stderr) = state.process.child.stderr.as_mut() {
129134
_ = stderr.read_to_string(&mut msg);
130135
}
131136
}
132137
let server_error = ServerError {
133138
message: format!("server exited with {status}: {msg}"),
134139
io: None,
135140
};
136-
self.server_exited = Some(server_error.clone());
141+
state.server_exited = Some(server_error.clone());
137142
server_error
138143
}
139144
Err(_) => e,

0 commit comments

Comments
 (0)