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:
Aleksey Kladov 2021-08-31 19:01:39 +03:00
parent 722a2a4690
commit d8a3d6f378
12 changed files with 242 additions and 271 deletions

View file

@ -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> {