Skip to content

Commit

Permalink
Auto merge of rust-lang#14070 - Veykril:proc-macro-api, r=Veykril
Browse files Browse the repository at this point in the history
Implement proc-macro-api versioning

So as it stands, we can't really change the proc-macro-api protocol at all without breaking all proc-macro servers again. To somewhat alleviate this we can move the supported ABI mess over to the proc-macro-api now by supporting multiple versions there (versions defined by us at least, not by rustc). Since the proc-macro-api protocol has no versioning scheme at the moment though, the best we can do here is add a new request to query the version from a server. Due to how the server currently works though, if it encounters an unknown request it will exit, meaning we can check if it is a server without support by checking if it exited after our version check request, that way we can support the current circulating server as well.

We need this since our span type will change from `TokenId` to something else at some point, but for that to work we need to comply with that the server expects. So knowing the version the server is using we can decide whether to send our new span data, or the tokenid (assuming we keep that information with our span data as well, alternatively we send irrelevant tokenids). That way we can keep old servers working while the user installations slowly migrate to newer servers that support the new spandata.
  • Loading branch information
bors committed Feb 3, 2023
2 parents 46846ea + 8e998c4 commit 6133e27
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 9 deletions.
4 changes: 2 additions & 2 deletions crates/proc-macro-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ impl ProcMacroServer {
/// Spawns an external process as the proc macro server and returns a client connected to it.
pub fn spawn(
process_path: AbsPathBuf,
args: impl IntoIterator<Item = impl AsRef<OsStr>>,
args: impl IntoIterator<Item = impl AsRef<OsStr>> + Clone,
) -> io::Result<ProcMacroServer> {
let process = ProcMacroProcessSrv::run(process_path, args)?;
Ok(ProcMacroServer { process: Arc::new(Mutex::new(process)) })
Expand Down Expand Up @@ -174,7 +174,7 @@ impl ProcMacro {
let response = self.process.lock().unwrap_or_else(|e| e.into_inner()).send_task(request)?;
match response {
msg::Response::ExpandMacro(it) => Ok(it.map(FlatTree::to_subtree)),
msg::Response::ListMacros { .. } => {
msg::Response::ListMacros(..) | msg::Response::ApiVersionCheck(..) => {
Err(ServerError { message: "unexpected response".to_string(), io: None })
}
}
Expand Down
5 changes: 5 additions & 0 deletions crates/proc-macro-api/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,21 @@ use crate::ProcMacroKind;

pub use crate::msg::flat::FlatTree;

pub const NO_VERSION_CHECK_VERSION: u32 = 0;
pub const CURRENT_API_VERSION: u32 = 1;

#[derive(Debug, Serialize, Deserialize)]
pub enum Request {
ListMacros { dylib_path: PathBuf },
ExpandMacro(ExpandMacro),
ApiVersionCheck {},
}

#[derive(Debug, Serialize, Deserialize)]
pub enum Response {
ListMacros(Result<Vec<(String, ProcMacroKind)>, String>),
ExpandMacro(Result<FlatTree, PanicMessage>),
ApiVersionCheck(u32),
}

#[derive(Debug, Serialize, Deserialize)]
Expand Down
47 changes: 40 additions & 7 deletions crates/proc-macro-api/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use paths::{AbsPath, AbsPathBuf};
use stdx::JodChild;

use crate::{
msg::{Message, Request, Response},
msg::{Message, Request, Response, CURRENT_API_VERSION},
ProcMacroKind, ServerError,
};

Expand All @@ -19,19 +19,52 @@ pub(crate) struct ProcMacroProcessSrv {
_process: Process,
stdin: ChildStdin,
stdout: BufReader<ChildStdout>,
version: u32,
}

impl ProcMacroProcessSrv {
pub(crate) fn run(
process_path: AbsPathBuf,
args: impl IntoIterator<Item = impl AsRef<OsStr>>,
args: impl IntoIterator<Item = impl AsRef<OsStr>> + Clone,
) -> io::Result<ProcMacroProcessSrv> {
let mut process = Process::run(process_path, args)?;
let (stdin, stdout) = process.stdio().expect("couldn't access child stdio");
let create_srv = || {
let mut process = Process::run(process_path.clone(), args.clone())?;
let (stdin, stdout) = process.stdio().expect("couldn't access child stdio");

io::Result::Ok(ProcMacroProcessSrv { _process: process, stdin, stdout, version: 0 })
};
let mut srv = create_srv()?;
tracing::info!("sending version check");
match srv.version_check() {
Ok(v) if v > CURRENT_API_VERSION => Err(io::Error::new(
io::ErrorKind::Other,
format!(
"proc-macro server's api version ({}) is newer than rust-analyzer's ({})",
v, CURRENT_API_VERSION
),
)),
Ok(v) => {
tracing::info!("got version {v}");
srv.version = v;
Ok(srv)
}
Err(e) => {
tracing::info!(%e, "proc-macro version check failed, restarting and assuming version 0");
create_srv()
}
}
}

let srv = ProcMacroProcessSrv { _process: process, stdin, stdout };
pub(crate) fn version_check(&mut self) -> Result<u32, ServerError> {
let request = Request::ApiVersionCheck {};
let response = self.send_task(request)?;

Ok(srv)
match response {
Response::ApiVersionCheck(version) => Ok(version),
Response::ExpandMacro { .. } | Response::ListMacros { .. } => {
Err(ServerError { message: "unexpected response".to_string(), io: None })
}
}
}

pub(crate) fn find_proc_macros(
Expand All @@ -44,7 +77,7 @@ impl ProcMacroProcessSrv {

match response {
Response::ListMacros(it) => Ok(it),
Response::ExpandMacro { .. } => {
Response::ExpandMacro { .. } | Response::ApiVersionCheck { .. } => {
Err(ServerError { message: "unexpected response".to_string(), io: None })
}
}
Expand Down
3 changes: 3 additions & 0 deletions crates/proc-macro-srv/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ pub fn run() -> io::Result<()> {
msg::Response::ListMacros(srv.list_macros(&dylib_path))
}
msg::Request::ExpandMacro(task) => msg::Response::ExpandMacro(srv.expand(task)),
msg::Request::ApiVersionCheck {} => {
msg::Response::ApiVersionCheck(proc_macro_api::msg::CURRENT_API_VERSION)
}
};
write_response(res)?
}
Expand Down

0 comments on commit 6133e27

Please sign in to comment.