mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-08-19 01:50:32 +00:00
internal: cleanup proc macro server error handlig
When dealing with proc macros, there are two very different kinds of errors: * first, usual errors of "proc macro panicked on this particular input" * second, the proc macro server might day if the user, eg, kills it First kind of errors are expected and are a normal output, while the second kind are genuine IO-errors. For this reason, we use a curious nested result here: `Result<Result<T, E1>, E2>` pattern, which is 100% inspired by http://sled.rs/errors.html
This commit is contained in:
parent
722a2a4690
commit
d8a3d6f378
12 changed files with 242 additions and 271 deletions
|
@ -7,8 +7,8 @@ mod proc_macro;
|
|||
#[allow(dead_code)]
|
||||
#[doc(hidden)]
|
||||
mod rustc_server;
|
||||
use libloading::Library;
|
||||
|
||||
use libloading::Library;
|
||||
use proc_macro_api::ProcMacroKind;
|
||||
|
||||
use super::PanicMessage;
|
||||
|
|
|
@ -7,8 +7,8 @@ mod proc_macro;
|
|||
#[allow(dead_code)]
|
||||
#[doc(hidden)]
|
||||
mod rustc_server;
|
||||
use libloading::Library;
|
||||
|
||||
use libloading::Library;
|
||||
use proc_macro_api::ProcMacroKind;
|
||||
|
||||
use super::PanicMessage;
|
||||
|
|
|
@ -7,8 +7,8 @@ mod proc_macro;
|
|||
#[allow(dead_code)]
|
||||
#[doc(hidden)]
|
||||
mod rustc_server;
|
||||
use libloading::Library;
|
||||
|
||||
use libloading::Library;
|
||||
use proc_macro_api::ProcMacroKind;
|
||||
|
||||
use super::PanicMessage;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
//! Driver for proc macro server
|
||||
use std::io;
|
||||
|
||||
use proc_macro_api::msg::{self, Message};
|
||||
|
||||
use crate::ProcMacroSrv;
|
||||
use proc_macro_api::msg::{self, Message};
|
||||
use std::io;
|
||||
|
||||
pub fn run() -> io::Result<()> {
|
||||
let mut srv = ProcMacroSrv::default();
|
||||
|
@ -10,22 +11,12 @@ pub fn run() -> io::Result<()> {
|
|||
|
||||
while let Some(req) = read_request(&mut buf)? {
|
||||
let res = match req {
|
||||
msg::Request::ListMacro(task) => srv.list_macros(&task).map(msg::Response::ListMacro),
|
||||
msg::Request::ExpansionMacro(task) => {
|
||||
srv.expand(task).map(msg::Response::ExpansionMacro)
|
||||
msg::Request::ListMacros { dylib_path } => {
|
||||
msg::Response::ListMacros(srv.list_macros(&dylib_path))
|
||||
}
|
||||
msg::Request::ExpandMacro(task) => msg::Response::ExpandMacro(srv.expand(task)),
|
||||
};
|
||||
|
||||
let msg = res.unwrap_or_else(|err| {
|
||||
msg::Response::Error(msg::ResponseError {
|
||||
code: msg::ErrorCode::ExpansionError,
|
||||
message: err,
|
||||
})
|
||||
});
|
||||
|
||||
if let Err(err) = write_response(msg) {
|
||||
eprintln!("Write message error: {}", err);
|
||||
}
|
||||
write_response(res)?
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -12,10 +12,8 @@
|
|||
#![allow(unreachable_pub)]
|
||||
|
||||
mod dylib;
|
||||
|
||||
mod abis;
|
||||
|
||||
use proc_macro_api::{ExpansionResult, ExpansionTask, FlatTree, ListMacrosResult, ListMacrosTask};
|
||||
use std::{
|
||||
collections::{hash_map::Entry, HashMap},
|
||||
env, fs,
|
||||
|
@ -23,14 +21,22 @@ use std::{
|
|||
time::SystemTime,
|
||||
};
|
||||
|
||||
use proc_macro_api::{
|
||||
msg::{ExpandMacro, FlatTree, PanicMessage},
|
||||
ProcMacroKind,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct ProcMacroSrv {
|
||||
expanders: HashMap<(PathBuf, SystemTime), dylib::Expander>,
|
||||
}
|
||||
|
||||
impl ProcMacroSrv {
|
||||
pub fn expand(&mut self, task: ExpansionTask) -> Result<ExpansionResult, String> {
|
||||
let expander = self.expander(task.lib.as_ref())?;
|
||||
pub fn expand(&mut self, task: ExpandMacro) -> Result<FlatTree, PanicMessage> {
|
||||
let expander = self.expander(task.lib.as_ref()).map_err(|err| {
|
||||
debug_assert!(false, "should list macros before asking to expand");
|
||||
PanicMessage(format!("failed to load macro: {}", err))
|
||||
})?;
|
||||
|
||||
let mut prev_env = HashMap::new();
|
||||
for (k, v) in &task.env {
|
||||
|
@ -51,15 +57,15 @@ impl ProcMacroSrv {
|
|||
}
|
||||
}
|
||||
|
||||
match result {
|
||||
Ok(expansion) => Ok(ExpansionResult { expansion }),
|
||||
Err(msg) => Err(format!("proc-macro panicked: {}", msg)),
|
||||
}
|
||||
result.map_err(PanicMessage)
|
||||
}
|
||||
|
||||
pub fn list_macros(&mut self, task: &ListMacrosTask) -> Result<ListMacrosResult, String> {
|
||||
let expander = self.expander(task.lib.as_ref())?;
|
||||
Ok(ListMacrosResult { macros: expander.list_macros() })
|
||||
pub(crate) fn list_macros(
|
||||
&mut self,
|
||||
dylib_path: &Path,
|
||||
) -> Result<Vec<(String, ProcMacroKind)>, String> {
|
||||
let expander = self.expander(dylib_path)?;
|
||||
Ok(expander.list_macros())
|
||||
}
|
||||
|
||||
fn expander(&mut self, path: &Path) -> Result<&dylib::Expander, String> {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
use crate::dylib;
|
||||
use crate::ProcMacroSrv;
|
||||
use expect_test::Expect;
|
||||
use proc_macro_api::ListMacrosTask;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub mod fixtures {
|
||||
|
@ -40,9 +39,9 @@ fn assert_expand_impl(macro_name: &str, input: &str, attr: Option<&str>, expect:
|
|||
expect.assert_eq(&format!("{:?}", res));
|
||||
}
|
||||
|
||||
pub fn list() -> Vec<String> {
|
||||
let task = ListMacrosTask { lib: fixtures::proc_macro_test_dylib_path() };
|
||||
pub(crate) fn list() -> Vec<String> {
|
||||
let dylib_path = fixtures::proc_macro_test_dylib_path();
|
||||
let mut srv = ProcMacroSrv::default();
|
||||
let res = srv.list_macros(&task).unwrap();
|
||||
res.macros.into_iter().map(|(name, kind)| format!("{} [{:?}]", name, kind)).collect()
|
||||
let res = srv.list_macros(&dylib_path).unwrap();
|
||||
res.into_iter().map(|(name, kind)| format!("{} [{:?}]", name, kind)).collect()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue