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.rs62
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();