Skip to content

Commit 4a1c7d1

Browse files
authored
Merge pull request rust-lang#18792 from Veykril/push-wonkvzozmmwz
Decouple proc-macro server protocol from the server implementation
2 parents a081215 + 042528a commit 4a1c7d1

File tree

18 files changed

+345
-315
lines changed

18 files changed

+345
-315
lines changed

src/tools/rust-analyzer/Cargo.lock

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1375,7 +1375,6 @@ dependencies = [
13751375
"memmap2",
13761376
"object 0.33.0",
13771377
"paths",
1378-
"proc-macro-api",
13791378
"proc-macro-test",
13801379
"ra-ap-rustc_lexer",
13811380
"span",

src/tools/rust-analyzer/crates/load-cargo/src/lib.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use ide_db::{
1414
prime_caches, ChangeWithProcMacros, FxHashMap, RootDatabase,
1515
};
1616
use itertools::Itertools;
17-
use proc_macro_api::{MacroDylib, ProcMacroServer};
17+
use proc_macro_api::{MacroDylib, ProcMacroClient};
1818
use project_model::{CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace};
1919
use span::Span;
2020
use vfs::{
@@ -42,7 +42,7 @@ pub fn load_workspace_at(
4242
cargo_config: &CargoConfig,
4343
load_config: &LoadCargoConfig,
4444
progress: &dyn Fn(String),
45-
) -> anyhow::Result<(RootDatabase, vfs::Vfs, Option<ProcMacroServer>)> {
45+
) -> anyhow::Result<(RootDatabase, vfs::Vfs, Option<ProcMacroClient>)> {
4646
let root = AbsPathBuf::assert_utf8(std::env::current_dir()?.join(root));
4747
let root = ProjectManifest::discover_single(&root)?;
4848
let mut workspace = ProjectWorkspace::load(root, cargo_config, progress)?;
@@ -59,7 +59,7 @@ pub fn load_workspace(
5959
ws: ProjectWorkspace,
6060
extra_env: &FxHashMap<String, String>,
6161
load_config: &LoadCargoConfig,
62-
) -> anyhow::Result<(RootDatabase, vfs::Vfs, Option<ProcMacroServer>)> {
62+
) -> anyhow::Result<(RootDatabase, vfs::Vfs, Option<ProcMacroClient>)> {
6363
let (sender, receiver) = unbounded();
6464
let mut vfs = vfs::Vfs::default();
6565
let mut loader = {
@@ -71,18 +71,18 @@ pub fn load_workspace(
7171
let proc_macro_server = match &load_config.with_proc_macro_server {
7272
ProcMacroServerChoice::Sysroot => ws
7373
.find_sysroot_proc_macro_srv()
74-
.and_then(|it| ProcMacroServer::spawn(&it, extra_env).map_err(Into::into))
74+
.and_then(|it| ProcMacroClient::spawn(&it, extra_env).map_err(Into::into))
7575
.map_err(|e| (e, true)),
7676
ProcMacroServerChoice::Explicit(path) => {
77-
ProcMacroServer::spawn(path, extra_env).map_err(Into::into).map_err(|e| (e, true))
77+
ProcMacroClient::spawn(path, extra_env).map_err(Into::into).map_err(|e| (e, true))
7878
}
7979
ProcMacroServerChoice::None => {
8080
Err((anyhow::format_err!("proc macro server disabled"), false))
8181
}
8282
};
8383
match &proc_macro_server {
8484
Ok(server) => {
85-
tracing::info!(path=%server.path(), "Proc-macro server started")
85+
tracing::info!(path=%server.server_path(), "Proc-macro server started")
8686
}
8787
Err((e, _)) => {
8888
tracing::info!(%e, "Failed to start proc-macro server")
@@ -362,7 +362,7 @@ impl SourceRootConfig {
362362

363363
/// Load the proc-macros for the given lib path, disabling all expanders whose names are in `ignored_macros`.
364364
pub fn load_proc_macro(
365-
server: &ProcMacroServer,
365+
server: &ProcMacroClient,
366366
path: &AbsPath,
367367
ignored_macros: &[Box<str>],
368368
) -> ProcMacroLoadResult {

src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs renamed to src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ use serde_derive::{Deserialize, Serialize};
99

1010
use crate::ProcMacroKind;
1111

12-
pub use crate::msg::flat::{
12+
pub use self::flat::{
1313
deserialize_span_data_index_map, serialize_span_data_index_map, FlatTree, SpanDataIndexMap,
14-
TokenId,
1514
};
15+
pub use span::TokenId;
1616

1717
// The versions of the server protocol
1818
pub const NO_VERSION_CHECK_VERSION: u32 = 0;

src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs renamed to src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@ use std::collections::VecDeque;
4040
use intern::Symbol;
4141
use rustc_hash::FxHashMap;
4242
use serde_derive::{Deserialize, Serialize};
43-
use span::{EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, TextRange};
43+
use span::{
44+
EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, TextRange, TokenId,
45+
};
4446

45-
use crate::msg::{ENCODE_CLOSE_SPAN_VERSION, EXTENDED_LEAF_DATA};
47+
use crate::legacy_protocol::msg::{ENCODE_CLOSE_SPAN_VERSION, EXTENDED_LEAF_DATA};
4648

4749
pub type SpanDataIndexMap =
4850
indexmap::IndexSet<Span, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
@@ -78,15 +80,6 @@ pub fn deserialize_span_data_index_map(map: &[u32]) -> SpanDataIndexMap {
7880
.collect()
7981
}
8082

81-
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
82-
pub struct TokenId(pub u32);
83-
84-
impl std::fmt::Debug for TokenId {
85-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86-
self.0.fmt(f)
87-
}
88-
}
89-
9083
#[derive(Serialize, Deserialize, Debug)]
9184
pub struct FlatTree {
9285
subtree: Vec<u32>,

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

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,26 @@
55
//! is used to provide basic infrastructure for communication between two
66
//! processes: Client (RA itself), Server (the external program)
77
8-
pub mod json;
9-
pub mod msg;
8+
pub mod legacy_protocol {
9+
pub mod json;
10+
pub mod msg;
11+
}
1012
mod process;
1113

1214
use paths::{AbsPath, AbsPathBuf};
1315
use span::Span;
1416
use std::{fmt, io, sync::Arc};
1517

16-
use serde::{Deserialize, Serialize};
17-
1818
use crate::{
19-
msg::{
19+
legacy_protocol::msg::{
2020
deserialize_span_data_index_map, flat::serialize_span_data_index_map, ExpandMacro,
21-
ExpnGlobals, FlatTree, PanicMessage, SpanDataIndexMap, HAS_GLOBAL_SPANS,
22-
RUST_ANALYZER_SPAN_SUPPORT,
21+
ExpandMacroData, ExpnGlobals, FlatTree, PanicMessage, Request, Response, SpanDataIndexMap,
22+
HAS_GLOBAL_SPANS, RUST_ANALYZER_SPAN_SUPPORT,
2323
},
24-
process::ProcMacroProcessSrv,
24+
process::ProcMacroServerProcess,
2525
};
2626

27-
#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
27+
#[derive(Copy, Clone, Eq, PartialEq, Debug, serde_derive::Serialize, serde_derive::Deserialize)]
2828
pub enum ProcMacroKind {
2929
CustomDerive,
3030
Attr,
@@ -37,12 +37,12 @@ pub enum ProcMacroKind {
3737
/// A handle to an external process which load dylibs with macros (.so or .dll)
3838
/// and runs actual macro expansion functions.
3939
#[derive(Debug)]
40-
pub struct ProcMacroServer {
40+
pub struct ProcMacroClient {
4141
/// Currently, the proc macro process expands all procedural macros sequentially.
4242
///
4343
/// That means that concurrent salsa requests may block each other when expanding proc macros,
4444
/// which is unfortunate, but simple and good enough for the time being.
45-
process: Arc<ProcMacroProcessSrv>,
45+
process: Arc<ProcMacroServerProcess>,
4646
path: AbsPathBuf,
4747
}
4848

@@ -56,13 +56,13 @@ impl MacroDylib {
5656
}
5757
}
5858

59-
/// A handle to a specific macro (a `#[proc_macro]` annotated function).
59+
/// A handle to a specific proc-macro (a `#[proc_macro]` annotated function).
6060
///
61-
/// It exists within a context of a specific [`ProcMacroProcess`] -- currently
62-
/// we share a single expander process for all macros.
61+
/// It exists within the context of a specific proc-macro server -- currently
62+
/// we share a single expander process for all macros within a workspace.
6363
#[derive(Debug, Clone)]
6464
pub struct ProcMacro {
65-
process: Arc<ProcMacroProcessSrv>,
65+
process: Arc<ProcMacroServerProcess>,
6666
dylib_path: Arc<AbsPathBuf>,
6767
name: Box<str>,
6868
kind: ProcMacroKind,
@@ -95,21 +95,22 @@ impl fmt::Display for ServerError {
9595
}
9696
}
9797

98-
impl ProcMacroServer {
98+
impl ProcMacroClient {
9999
/// Spawns an external process as the proc macro server and returns a client connected to it.
100100
pub fn spawn(
101101
process_path: &AbsPath,
102102
env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>
103103
+ Clone,
104-
) -> io::Result<ProcMacroServer> {
105-
let process = ProcMacroProcessSrv::run(process_path, env)?;
106-
Ok(ProcMacroServer { process: Arc::new(process), path: process_path.to_owned() })
104+
) -> io::Result<ProcMacroClient> {
105+
let process = ProcMacroServerProcess::run(process_path, env)?;
106+
Ok(ProcMacroClient { process: Arc::new(process), path: process_path.to_owned() })
107107
}
108108

109-
pub fn path(&self) -> &AbsPath {
109+
pub fn server_path(&self) -> &AbsPath {
110110
&self.path
111111
}
112112

113+
/// Loads a proc-macro dylib into the server process returning a list of `ProcMacro`s loaded.
113114
pub fn load_dylib(&self, dylib: MacroDylib) -> Result<Vec<ProcMacro>, ServerError> {
114115
let _p = tracing::info_span!("ProcMacroServer::load_dylib").entered();
115116
let macros = self.process.find_proc_macros(&dylib.path)?;
@@ -160,7 +161,7 @@ impl ProcMacro {
160161
let call_site = span_data_table.insert_full(call_site).0;
161162
let mixed_site = span_data_table.insert_full(mixed_site).0;
162163
let task = ExpandMacro {
163-
data: msg::ExpandMacroData {
164+
data: ExpandMacroData {
164165
macro_body: FlatTree::new(subtree, version, &mut span_data_table),
165166
macro_name: self.name.to_string(),
166167
attributes: attr
@@ -182,13 +183,13 @@ impl ProcMacro {
182183
current_dir,
183184
};
184185

185-
let response = self.process.send_task(msg::Request::ExpandMacro(Box::new(task)))?;
186+
let response = self.process.send_task(Request::ExpandMacro(Box::new(task)))?;
186187

187188
match response {
188-
msg::Response::ExpandMacro(it) => {
189+
Response::ExpandMacro(it) => {
189190
Ok(it.map(|tree| FlatTree::to_subtree_resolved(tree, version, &span_data_table)))
190191
}
191-
msg::Response::ExpandMacroExtended(it) => Ok(it.map(|resp| {
192+
Response::ExpandMacroExtended(it) => Ok(it.map(|resp| {
192193
FlatTree::to_subtree_resolved(
193194
resp.tree,
194195
version,

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

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,18 @@ use paths::AbsPath;
1111
use stdx::JodChild;
1212

1313
use crate::{
14-
json::{read_json, write_json},
15-
msg::{Message, Request, Response, SpanMode, CURRENT_API_VERSION, RUST_ANALYZER_SPAN_SUPPORT},
14+
legacy_protocol::{
15+
json::{read_json, write_json},
16+
msg::{
17+
Message, Request, Response, ServerConfig, SpanMode, CURRENT_API_VERSION,
18+
RUST_ANALYZER_SPAN_SUPPORT,
19+
},
20+
},
1621
ProcMacroKind, ServerError,
1722
};
1823

1924
#[derive(Debug)]
20-
pub(crate) struct ProcMacroProcessSrv {
25+
pub(crate) struct ProcMacroServerProcess {
2126
/// The state of the proc-macro server process, the protocol is currently strictly sequential
2227
/// hence the lock on the state.
2328
state: Mutex<ProcessSrvState>,
@@ -34,24 +39,24 @@ struct ProcessSrvState {
3439
stdout: BufReader<ChildStdout>,
3540
}
3641

37-
impl ProcMacroProcessSrv {
42+
impl ProcMacroServerProcess {
3843
pub(crate) fn run(
3944
process_path: &AbsPath,
4045
env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>
4146
+ Clone,
42-
) -> io::Result<ProcMacroProcessSrv> {
43-
let create_srv = |null_stderr| {
44-
let mut process = Process::run(process_path, env.clone(), null_stderr)?;
47+
) -> io::Result<ProcMacroServerProcess> {
48+
let create_srv = || {
49+
let mut process = Process::run(process_path, env.clone())?;
4550
let (stdin, stdout) = process.stdio().expect("couldn't access child stdio");
4651

47-
io::Result::Ok(ProcMacroProcessSrv {
52+
io::Result::Ok(ProcMacroServerProcess {
4853
state: Mutex::new(ProcessSrvState { process, stdin, stdout }),
4954
version: 0,
5055
mode: SpanMode::Id,
5156
exited: OnceLock::new(),
5257
})
5358
};
54-
let mut srv = create_srv(true)?;
59+
let mut srv = create_srv()?;
5560
tracing::info!("sending proc-macro server version check");
5661
match srv.version_check() {
5762
Ok(v) if v > CURRENT_API_VERSION => Err(io::Error::new(
@@ -62,7 +67,6 @@ impl ProcMacroProcessSrv {
6267
)),
6368
Ok(v) => {
6469
tracing::info!("Proc-macro server version: {v}");
65-
srv = create_srv(false)?;
6670
srv.version = v;
6771
if srv.version >= RUST_ANALYZER_SPAN_SUPPORT {
6872
if let Ok(mode) = srv.enable_rust_analyzer_spans() {
@@ -73,8 +77,10 @@ impl ProcMacroProcessSrv {
7377
Ok(srv)
7478
}
7579
Err(e) => {
76-
tracing::info!(%e, "proc-macro version check failed, restarting and assuming version 0");
77-
create_srv(false)
80+
tracing::info!(%e, "proc-macro version check failed");
81+
Err(
82+
io::Error::new(io::ErrorKind::Other, format!("proc-macro server version check failed: {e}")),
83+
)
7884
}
7985
}
8086
}
@@ -98,13 +104,11 @@ impl ProcMacroProcessSrv {
98104
}
99105

100106
fn enable_rust_analyzer_spans(&self) -> Result<SpanMode, ServerError> {
101-
let request = Request::SetConfig(crate::msg::ServerConfig {
102-
span_mode: crate::msg::SpanMode::RustAnalyzer,
103-
});
107+
let request = Request::SetConfig(ServerConfig { span_mode: SpanMode::RustAnalyzer });
104108
let response = self.send_task(request)?;
105109

106110
match response {
107-
Response::SetConfig(crate::msg::ServerConfig { span_mode }) => Ok(span_mode),
111+
Response::SetConfig(ServerConfig { span_mode }) => Ok(span_mode),
108112
_ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),
109113
}
110114
}
@@ -182,9 +186,8 @@ impl Process {
182186
fn run(
183187
path: &AbsPath,
184188
env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>,
185-
null_stderr: bool,
186189
) -> io::Result<Process> {
187-
let child = JodChild(mk_child(path, env, null_stderr)?);
190+
let child = JodChild(mk_child(path, env)?);
188191
Ok(Process { child })
189192
}
190193

@@ -200,15 +203,14 @@ impl Process {
200203
fn mk_child(
201204
path: &AbsPath,
202205
env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>,
203-
null_stderr: bool,
204206
) -> io::Result<Child> {
205207
#[allow(clippy::disallowed_methods)]
206208
let mut cmd = Command::new(path);
207209
cmd.envs(env)
208210
.env("RUST_ANALYZER_INTERNALS_DO_NOT_USE", "this is unstable")
209211
.stdin(Stdio::piped())
210212
.stdout(Stdio::piped())
211-
.stderr(if null_stderr { Stdio::null() } else { Stdio::inherit() });
213+
.stderr(Stdio::inherit());
212214
if cfg!(windows) {
213215
let mut path_var = std::ffi::OsString::new();
214216
path_var.push(path.parent().unwrap().parent().unwrap());

0 commit comments

Comments
 (0)