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.rs | 62 |
1 files changed, 57 insertions, 5 deletions
diff --git a/crates/proc-macro-srv/src/lib.rs b/crates/proc-macro-srv/src/lib.rs index 920d58b4e9..c548dc620a 100644 --- a/crates/proc-macro-srv/src/lib.rs +++ b/crates/proc-macro-srv/src/lib.rs @@ -22,8 +22,11 @@ )] #![deny(deprecated_safe, clippy::undocumented_unsafe_blocks)] +#[cfg(not(feature = "in-rust-tree"))] +extern crate proc_macro as rustc_proc_macro; #[cfg(feature = "in-rust-tree")] extern crate rustc_driver as _; +#[cfg(feature = "in-rust-tree")] extern crate rustc_proc_macro; #[cfg(not(feature = "in-rust-tree"))] @@ -41,6 +44,7 @@ use std::{ env, ffi::OsString, fs, + ops::Range, path::{Path, PathBuf}, sync::{Arc, Mutex, PoisonError}, thread, @@ -92,16 +96,50 @@ impl<'env> ProcMacroSrv<'env> { } } +#[derive(Debug)] +pub enum ProcMacroClientError { + Cancelled { reason: String }, + Io(std::io::Error), + Protocol(String), + Eof, +} + +#[derive(Debug)] +pub enum ProcMacroPanicMarker { + Cancelled { reason: String }, + Internal { reason: String }, +} + pub type ProcMacroClientHandle<'a> = &'a mut (dyn ProcMacroClientInterface + Sync + Send); pub trait ProcMacroClientInterface { fn file(&mut self, file_id: span::FileId) -> String; fn source_text(&mut self, span: Span) -> Option<String>; fn local_file(&mut self, file_id: span::FileId) -> Option<String>; + /// Line and column are 1-based. + fn line_column(&mut self, span: Span) -> Option<(u32, u32)>; + + fn byte_range(&mut self, span: Span) -> Range<usize>; } const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; +pub enum ExpandError { + Panic(PanicMessage), + Cancelled { reason: Option<String> }, + Internal { reason: Option<String> }, +} + +impl ExpandError { + pub fn into_string(self) -> Option<String> { + match self { + ExpandError::Panic(panic_message) => panic_message.into_string(), + ExpandError::Cancelled { reason } => reason, + ExpandError::Internal { reason } => reason, + } + } +} + impl ProcMacroSrv<'_> { pub fn expand<S: ProcMacroSrvSpan>( &self, @@ -115,10 +153,10 @@ impl ProcMacroSrv<'_> { call_site: S, mixed_site: S, callback: Option<ProcMacroClientHandle<'_>>, - ) -> Result<token_stream::TokenStream<S>, PanicMessage> { + ) -> Result<token_stream::TokenStream<S>, ExpandError> { let snapped_env = self.env; - let expander = self.expander(lib.as_ref()).map_err(|err| PanicMessage { - message: Some(format!("failed to load macro: {err}")), + let expander = self.expander(lib.as_ref()).map_err(|err| ExpandError::Internal { + reason: Some(format!("failed to load macro: {err}")), })?; let prev_env = EnvChange::apply(snapped_env, env, current_dir.as_ref().map(<_>::as_ref)); @@ -136,8 +174,22 @@ impl ProcMacroSrv<'_> { ) }); match thread.unwrap().join() { - Ok(res) => res, - Err(e) => std::panic::resume_unwind(e), + Ok(res) => res.map_err(ExpandError::Panic), + + Err(payload) => { + if let Some(marker) = payload.downcast_ref::<ProcMacroPanicMarker>() { + return match marker { + ProcMacroPanicMarker::Cancelled { reason } => { + Err(ExpandError::Cancelled { reason: Some(reason.clone()) }) + } + ProcMacroPanicMarker::Internal { reason } => { + Err(ExpandError::Internal { reason: Some(reason.clone()) }) + } + }; + } + + std::panic::resume_unwind(payload) + } } }); prev_env.rollback(); |