Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/proc-macro-srv/src/lib.rs')
-rw-r--r--crates/proc-macro-srv/src/lib.rs71
1 files changed, 38 insertions, 33 deletions
diff --git a/crates/proc-macro-srv/src/lib.rs b/crates/proc-macro-srv/src/lib.rs
index 223c5a54b7..cb97882c58 100644
--- a/crates/proc-macro-srv/src/lib.rs
+++ b/crates/proc-macro-srv/src/lib.rs
@@ -27,7 +27,6 @@ extern crate ra_ap_rustc_lexer as rustc_lexer;
extern crate rustc_lexer;
mod dylib;
-mod proc_macros;
mod server_impl;
use std::{
@@ -41,10 +40,13 @@ use std::{
};
use paths::{Utf8Path, Utf8PathBuf};
-use span::{Span, TokenId};
+use span::Span;
+use temp_dir::TempDir;
use crate::server_impl::TokenStream;
+pub use crate::server_impl::token_id::SpanId;
+
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum ProcMacroKind {
CustomDerive,
@@ -57,11 +59,16 @@ pub const RUSTC_VERSION_STRING: &str = env!("RUSTC_VERSION");
pub struct ProcMacroSrv<'env> {
expanders: Mutex<HashMap<Utf8PathBuf, Arc<dylib::Expander>>>,
env: &'env EnvSnapshot,
+ temp_dir: TempDir,
}
impl<'env> ProcMacroSrv<'env> {
pub fn new(env: &'env EnvSnapshot) -> Self {
- Self { expanders: Default::default(), env }
+ Self {
+ expanders: Default::default(),
+ env,
+ temp_dir: TempDir::with_prefix("proc-macro-srv").unwrap(),
+ }
}
}
@@ -71,18 +78,19 @@ impl ProcMacroSrv<'_> {
pub fn expand<S: ProcMacroSrvSpan>(
&self,
lib: impl AsRef<Utf8Path>,
- env: Vec<(String, String)>,
+ env: &[(String, String)],
current_dir: Option<impl AsRef<Path>>,
- macro_name: String,
+ macro_name: &str,
macro_body: tt::TopSubtree<S>,
attribute: Option<tt::TopSubtree<S>>,
def_site: S,
call_site: S,
mixed_site: S,
- ) -> Result<Vec<tt::TokenTree<S>>, String> {
+ ) -> Result<Vec<tt::TokenTree<S>>, PanicMessage> {
let snapped_env = self.env;
- let expander =
- self.expander(lib.as_ref()).map_err(|err| format!("failed to load macro: {err}"))?;
+ let expander = self.expander(lib.as_ref()).map_err(|err| PanicMessage {
+ message: Some(format!("failed to load macro: {err}")),
+ })?;
let prev_env = EnvChange::apply(snapped_env, env, current_dir.as_ref().map(<_>::as_ref));
@@ -91,11 +99,11 @@ impl ProcMacroSrv<'_> {
let result = thread::scope(|s| {
let thread = thread::Builder::new()
.stack_size(EXPANDER_STACK_SIZE)
- .name(macro_name.clone())
+ .name(macro_name.to_owned())
.spawn_scoped(s, move || {
expander
.expand(
- &macro_name,
+ macro_name,
server_impl::TopSubtree(macro_body.0.into_vec()),
attribute.map(|it| server_impl::TopSubtree(it.0.into_vec())),
def_site,
@@ -104,12 +112,7 @@ impl ProcMacroSrv<'_> {
)
.map(|tt| tt.0)
});
- let res = match thread {
- Ok(handle) => handle.join(),
- Err(e) => return Err(e.to_string()),
- };
-
- match res {
+ match thread.unwrap().join() {
Ok(res) => res,
Err(e) => std::panic::resume_unwind(e),
}
@@ -124,12 +127,12 @@ impl ProcMacroSrv<'_> {
dylib_path: &Utf8Path,
) -> Result<Vec<(String, ProcMacroKind)>, String> {
let expander = self.expander(dylib_path)?;
- Ok(expander.list_macros())
+ Ok(expander.list_macros().map(|(k, v)| (k.to_owned(), v)).collect())
}
fn expander(&self, path: &Utf8Path) -> Result<Arc<dylib::Expander>, String> {
let expander = || {
- let expander = dylib::Expander::new(path)
+ let expander = dylib::Expander::new(&self.temp_dir, path)
.map_err(|err| format!("Cannot create expander for {path}: {err}",));
expander.map(Arc::new)
};
@@ -159,8 +162,8 @@ pub trait ProcMacroSrvSpan: Copy + Send {
fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server;
}
-impl ProcMacroSrvSpan for TokenId {
- type Server = server_impl::token_id::TokenIdServer;
+impl ProcMacroSrvSpan for SpanId {
+ type Server = server_impl::token_id::SpanIdServer;
fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server {
Self::Server { call_site, def_site, mixed_site }
@@ -178,6 +181,8 @@ impl ProcMacroSrvSpan for Span {
}
}
}
+
+#[derive(Debug, Clone)]
pub struct PanicMessage {
message: Option<String>,
}
@@ -201,7 +206,7 @@ impl Default for EnvSnapshot {
static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
struct EnvChange<'snap> {
- changed_vars: Vec<String>,
+ changed_vars: Vec<&'snap str>,
prev_working_dir: Option<PathBuf>,
snap: &'snap EnvSnapshot,
_guard: std::sync::MutexGuard<'snap, ()>,
@@ -210,7 +215,7 @@ struct EnvChange<'snap> {
impl<'snap> EnvChange<'snap> {
fn apply(
snap: &'snap EnvSnapshot,
- new_vars: Vec<(String, String)>,
+ new_vars: &'snap [(String, String)],
current_dir: Option<&Path>,
) -> EnvChange<'snap> {
let guard = ENV_LOCK.lock().unwrap_or_else(std::sync::PoisonError::into_inner);
@@ -230,11 +235,11 @@ impl<'snap> EnvChange<'snap> {
EnvChange {
snap,
changed_vars: new_vars
- .into_iter()
+ .iter()
.map(|(k, v)| {
// SAFETY: We have acquired the environment lock
- unsafe { env::set_var(&k, v) };
- k
+ unsafe { env::set_var(k, v) };
+ &**k
})
.collect(),
prev_working_dir,
@@ -257,14 +262,14 @@ impl Drop for EnvChange<'_> {
}
}
- if let Some(dir) = &self.prev_working_dir {
- if let Err(err) = std::env::set_current_dir(dir) {
- eprintln!(
- "Failed to set the current working dir to {}. Error: {:?}",
- dir.display(),
- err
- )
- }
+ if let Some(dir) = &self.prev_working_dir
+ && let Err(err) = std::env::set_current_dir(dir)
+ {
+ eprintln!(
+ "Failed to set the current working dir to {}. Error: {:?}",
+ dir.display(),
+ err
+ )
}
}
}