diff options
Diffstat (limited to 'src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs')
| -rw-r--r-- | src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs | 71 |
1 files changed, 38 insertions, 33 deletions
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index 223c5a54b70..cb97882c585 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/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( - ¯o_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 + ) } } } |
