Skip to content

Commit 1975c98

Browse files
committed
Reorganize proc-macro-srv
1 parent 8971681 commit 1975c98

File tree

5 files changed

+131
-148
lines changed

5 files changed

+131
-148
lines changed

src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ impl SpanTransformer for SpanTrans {
2424
_: &mut Self::Table,
2525
span: Self::Span,
2626
) -> proc_macro_api::legacy_protocol::SpanId {
27-
proc_macro_api::legacy_protocol::SpanId(span.0 as u32)
27+
proc_macro_api::legacy_protocol::SpanId(span.0)
2828
}
2929
fn span_for_token_id(
3030
_: &Self::Table,
3131
id: proc_macro_api::legacy_protocol::SpanId,
3232
) -> Self::Span {
33-
SpanId(id.0 as u32)
33+
SpanId(id.0)
3434
}
3535
}
3636

@@ -99,7 +99,7 @@ fn run_json() -> io::Result<()> {
9999
lib,
100100
&env,
101101
current_dir,
102-
macro_name,
102+
&macro_name,
103103
macro_body,
104104
attributes,
105105
def_site,
@@ -112,6 +112,7 @@ fn run_json() -> io::Result<()> {
112112
CURRENT_API_VERSION,
113113
)
114114
})
115+
.map_err(|e| e.into_string().unwrap_or_default())
115116
.map_err(msg::PanicMessage)
116117
}),
117118
SpanMode::RustAnalyzer => msg::Response::ExpandMacroExtended({
@@ -130,7 +131,7 @@ fn run_json() -> io::Result<()> {
130131
lib,
131132
&env,
132133
current_dir,
133-
macro_name,
134+
&macro_name,
134135
macro_body,
135136
attributes,
136137
def_site,
@@ -151,6 +152,7 @@ fn run_json() -> io::Result<()> {
151152
tree,
152153
span_data_table,
153154
})
155+
.map_err(|e| e.into_string().unwrap_or_default())
154156
.map_err(msg::PanicMessage)
155157
}),
156158
}

src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs

Lines changed: 97 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Handles dynamic library loading for proc macro
22
3+
mod proc_macros;
34
mod version;
45

56
use proc_macro::bridge;
@@ -10,57 +11,56 @@ use libloading::Library;
1011
use object::Object;
1112
use paths::{Utf8Path, Utf8PathBuf};
1213

13-
use crate::{ProcMacroKind, ProcMacroSrvSpan, proc_macros::ProcMacros, server_impl::TopSubtree};
14+
use crate::{
15+
PanicMessage, ProcMacroKind, ProcMacroSrvSpan, dylib::proc_macros::ProcMacros,
16+
server_impl::TopSubtree,
17+
};
1418

15-
/// Loads dynamic library in platform dependent manner.
16-
///
17-
/// For unix, you have to use RTLD_DEEPBIND flag to escape problems described
18-
/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample)
19-
/// and [here](https://github.com/rust-lang/rust/issues/60593).
20-
///
21-
/// Usage of RTLD_DEEPBIND
22-
/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample/issues/1)
23-
///
24-
/// It seems that on Windows that behaviour is default, so we do nothing in that case.
25-
///
26-
/// # Safety
27-
///
28-
/// The caller is responsible for ensuring that the path is valid proc-macro library
29-
#[cfg(windows)]
30-
unsafe fn load_library(file: &Utf8Path) -> Result<Library, libloading::Error> {
31-
// SAFETY: The caller is responsible for ensuring that the path is valid proc-macro library
32-
unsafe { Library::new(file) }
19+
pub(crate) struct Expander {
20+
inner: ProcMacroLibrary,
21+
modified_time: SystemTime,
3322
}
3423

35-
/// Loads dynamic library in platform dependent manner.
36-
///
37-
/// For unix, you have to use RTLD_DEEPBIND flag to escape problems described
38-
/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample)
39-
/// and [here](https://github.com/rust-lang/rust/issues/60593).
40-
///
41-
/// Usage of RTLD_DEEPBIND
42-
/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample/issues/1)
43-
///
44-
/// It seems that on Windows that behaviour is default, so we do nothing in that case.
45-
///
46-
/// # Safety
47-
///
48-
/// The caller is responsible for ensuring that the path is valid proc-macro library
49-
#[cfg(unix)]
50-
unsafe fn load_library(file: &Utf8Path) -> Result<Library, libloading::Error> {
51-
// not defined by POSIX, different values on mips vs other targets
52-
#[cfg(target_env = "gnu")]
53-
use libc::RTLD_DEEPBIND;
54-
use libloading::os::unix::Library as UnixLibrary;
55-
// defined by POSIX
56-
use libloading::os::unix::RTLD_NOW;
24+
impl Expander {
25+
pub(crate) fn new(
26+
temp_dir: &TempDir,
27+
lib: &Utf8Path,
28+
) -> Result<Expander, LoadProcMacroDylibError> {
29+
// Some libraries for dynamic loading require canonicalized path even when it is
30+
// already absolute
31+
let lib = lib.canonicalize_utf8()?;
32+
let modified_time = fs::metadata(&lib).and_then(|it| it.modified())?;
5733

58-
// MUSL and bionic don't have it..
59-
#[cfg(not(target_env = "gnu"))]
60-
const RTLD_DEEPBIND: std::os::raw::c_int = 0x0;
34+
let path = ensure_file_with_lock_free_access(temp_dir, &lib)?;
35+
let library = ProcMacroLibrary::open(path.as_ref())?;
6136

62-
// SAFETY: The caller is responsible for ensuring that the path is valid proc-macro library
63-
unsafe { UnixLibrary::open(Some(file), RTLD_NOW | RTLD_DEEPBIND).map(|lib| lib.into()) }
37+
Ok(Expander { inner: library, modified_time })
38+
}
39+
40+
pub(crate) fn expand<S: ProcMacroSrvSpan>(
41+
&self,
42+
macro_name: &str,
43+
macro_body: TopSubtree<S>,
44+
attributes: Option<TopSubtree<S>>,
45+
def_site: S,
46+
call_site: S,
47+
mixed_site: S,
48+
) -> Result<TopSubtree<S>, PanicMessage>
49+
where
50+
<S::Server as bridge::server::Types>::TokenStream: Default,
51+
{
52+
self.inner
53+
.proc_macros
54+
.expand(macro_name, macro_body, attributes, def_site, call_site, mixed_site)
55+
}
56+
57+
pub(crate) fn list_macros(&self) -> impl Iterator<Item = (&str, ProcMacroKind)> {
58+
self.inner.proc_macros.list_macros()
59+
}
60+
61+
pub(crate) fn modified_time(&self) -> SystemTime {
62+
self.modified_time
63+
}
6464
}
6565

6666
#[derive(Debug)]
@@ -134,57 +134,6 @@ impl ProcMacroLibrary {
134134
}
135135
}
136136

137-
// Drop order matters as we can't remove the dylib before the library is unloaded
138-
pub(crate) struct Expander {
139-
inner: ProcMacroLibrary,
140-
_remove_on_drop: RemoveFileOnDrop,
141-
modified_time: SystemTime,
142-
}
143-
144-
impl Expander {
145-
pub(crate) fn new(
146-
temp_dir: &TempDir,
147-
lib: &Utf8Path,
148-
) -> Result<Expander, LoadProcMacroDylibError> {
149-
// Some libraries for dynamic loading require canonicalized path even when it is
150-
// already absolute
151-
let lib = lib.canonicalize_utf8()?;
152-
let modified_time = fs::metadata(&lib).and_then(|it| it.modified())?;
153-
154-
let path = ensure_file_with_lock_free_access(temp_dir, &lib)?;
155-
let library = ProcMacroLibrary::open(path.as_ref())?;
156-
157-
Ok(Expander { inner: library, _remove_on_drop: RemoveFileOnDrop(path), modified_time })
158-
}
159-
160-
pub(crate) fn expand<S: ProcMacroSrvSpan>(
161-
&self,
162-
macro_name: &str,
163-
macro_body: TopSubtree<S>,
164-
attributes: Option<TopSubtree<S>>,
165-
def_site: S,
166-
call_site: S,
167-
mixed_site: S,
168-
) -> Result<TopSubtree<S>, String>
169-
where
170-
<S::Server as bridge::server::Types>::TokenStream: Default,
171-
{
172-
let result = self
173-
.inner
174-
.proc_macros
175-
.expand(macro_name, macro_body, attributes, def_site, call_site, mixed_site);
176-
result.map_err(|e| e.into_string().unwrap_or_default())
177-
}
178-
179-
pub(crate) fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
180-
self.inner.proc_macros.list_macros()
181-
}
182-
183-
pub(crate) fn modified_time(&self) -> SystemTime {
184-
self.modified_time
185-
}
186-
}
187-
188137
fn invalid_data_err(e: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> io::Error {
189138
io::Error::new(io::ErrorKind::InvalidData, e)
190139
}
@@ -214,15 +163,6 @@ fn find_registrar_symbol(obj: &object::File<'_>) -> object::Result<Option<String
214163
}))
215164
}
216165

217-
struct RemoveFileOnDrop(Utf8PathBuf);
218-
impl Drop for RemoveFileOnDrop {
219-
fn drop(&mut self) {
220-
#[cfg(windows)]
221-
std::fs::remove_file(&self.0).unwrap();
222-
_ = self.0;
223-
}
224-
}
225-
226166
/// Copy the dylib to temp directory to prevent locking in Windows
227167
#[cfg(windows)]
228168
fn ensure_file_with_lock_free_access(
@@ -259,3 +199,54 @@ fn ensure_file_with_lock_free_access(
259199
) -> io::Result<Utf8PathBuf> {
260200
Ok(path.to_owned())
261201
}
202+
203+
/// Loads dynamic library in platform dependent manner.
204+
///
205+
/// For unix, you have to use RTLD_DEEPBIND flag to escape problems described
206+
/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample)
207+
/// and [here](https://github.com/rust-lang/rust/issues/60593).
208+
///
209+
/// Usage of RTLD_DEEPBIND
210+
/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample/issues/1)
211+
///
212+
/// It seems that on Windows that behaviour is default, so we do nothing in that case.
213+
///
214+
/// # Safety
215+
///
216+
/// The caller is responsible for ensuring that the path is valid proc-macro library
217+
#[cfg(windows)]
218+
unsafe fn load_library(file: &Utf8Path) -> Result<Library, libloading::Error> {
219+
// SAFETY: The caller is responsible for ensuring that the path is valid proc-macro library
220+
unsafe { Library::new(file) }
221+
}
222+
223+
/// Loads dynamic library in platform dependent manner.
224+
///
225+
/// For unix, you have to use RTLD_DEEPBIND flag to escape problems described
226+
/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample)
227+
/// and [here](https://github.com/rust-lang/rust/issues/60593).
228+
///
229+
/// Usage of RTLD_DEEPBIND
230+
/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample/issues/1)
231+
///
232+
/// It seems that on Windows that behaviour is default, so we do nothing in that case.
233+
///
234+
/// # Safety
235+
///
236+
/// The caller is responsible for ensuring that the path is valid proc-macro library
237+
#[cfg(unix)]
238+
unsafe fn load_library(file: &Utf8Path) -> Result<Library, libloading::Error> {
239+
// not defined by POSIX, different values on mips vs other targets
240+
#[cfg(target_env = "gnu")]
241+
use libc::RTLD_DEEPBIND;
242+
use libloading::os::unix::Library as UnixLibrary;
243+
// defined by POSIX
244+
use libloading::os::unix::RTLD_NOW;
245+
246+
// MUSL and bionic don't have it..
247+
#[cfg(not(target_env = "gnu"))]
248+
const RTLD_DEEPBIND: std::os::raw::c_int = 0x0;
249+
250+
// SAFETY: The caller is responsible for ensuring that the path is valid proc-macro library
251+
unsafe { UnixLibrary::open(Some(file), RTLD_NOW | RTLD_DEEPBIND).map(|lib| lib.into()) }
252+
}

src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs renamed to src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -75,20 +75,13 @@ impl ProcMacros {
7575
Err(bridge::PanicMessage::String(format!("proc-macro `{macro_name}` is missing")).into())
7676
}
7777

78-
pub(crate) fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
79-
self.0
80-
.iter()
81-
.map(|proc_macro| match proc_macro {
82-
bridge::client::ProcMacro::CustomDerive { trait_name, .. } => {
83-
(trait_name.to_string(), ProcMacroKind::CustomDerive)
84-
}
85-
bridge::client::ProcMacro::Bang { name, .. } => {
86-
(name.to_string(), ProcMacroKind::Bang)
87-
}
88-
bridge::client::ProcMacro::Attr { name, .. } => {
89-
(name.to_string(), ProcMacroKind::Attr)
90-
}
91-
})
92-
.collect()
78+
pub(crate) fn list_macros(&self) -> impl Iterator<Item = (&str, ProcMacroKind)> {
79+
self.0.iter().map(|proc_macro| match *proc_macro {
80+
bridge::client::ProcMacro::CustomDerive { trait_name, .. } => {
81+
(trait_name, ProcMacroKind::CustomDerive)
82+
}
83+
bridge::client::ProcMacro::Bang { name, .. } => (name, ProcMacroKind::Bang),
84+
bridge::client::ProcMacro::Attr { name, .. } => (name, ProcMacroKind::Attr),
85+
})
9386
}
9487
}

0 commit comments

Comments
 (0)