Skip to content

Commit b189b49

Browse files
Add (and use) sysroot ABI when building rust-analyzer in-tree
1 parent 81597bd commit b189b49

File tree

6 files changed

+915
-2
lines changed

6 files changed

+915
-2
lines changed

src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@ expect-test = "1.4.0"
3030

3131
# used as proc macro test targets
3232
proc-macro-test = { path = "../proc-macro-test" }
33+
34+
[features]
35+
in-rust-tree = []
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//! Macro ABI for version internal of rustc
2+
3+
extern crate proc_macro;
4+
5+
#[allow(dead_code)]
6+
#[doc(hidden)]
7+
mod rustc_server;
8+
9+
use libloading::Library;
10+
use proc_macro_api::ProcMacroKind;
11+
12+
use super::PanicMessage;
13+
14+
pub(crate) struct Abi {
15+
exported_macros: Vec<proc_macro::bridge::client::ProcMacro>,
16+
}
17+
18+
impl From<proc_macro::bridge::PanicMessage> for PanicMessage {
19+
fn from(p: proc_macro::bridge::PanicMessage) -> Self {
20+
Self { message: p.as_str().map(|s| s.to_string()) }
21+
}
22+
}
23+
24+
impl Abi {
25+
pub unsafe fn from_lib(lib: &Library, symbol_name: String) -> Result<Abi, libloading::Error> {
26+
let macros: libloading::Symbol<'_, &&[proc_macro::bridge::client::ProcMacro]> =
27+
lib.get(symbol_name.as_bytes())?;
28+
Ok(Self { exported_macros: macros.to_vec() })
29+
}
30+
31+
pub fn expand(
32+
&self,
33+
macro_name: &str,
34+
macro_body: &tt::Subtree,
35+
attributes: Option<&tt::Subtree>,
36+
) -> Result<tt::Subtree, PanicMessage> {
37+
let parsed_body = rustc_server::TokenStream::with_subtree(macro_body.clone());
38+
39+
let parsed_attributes = attributes.map_or(rustc_server::TokenStream::new(), |attr| {
40+
rustc_server::TokenStream::with_subtree(attr.clone())
41+
});
42+
43+
for proc_macro in &self.exported_macros {
44+
match proc_macro {
45+
proc_macro::bridge::client::ProcMacro::CustomDerive {
46+
trait_name, client, ..
47+
} if *trait_name == macro_name => {
48+
let res = client.run(
49+
&proc_macro::bridge::server::SameThread,
50+
rustc_server::Rustc::default(),
51+
parsed_body,
52+
true,
53+
);
54+
return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
55+
}
56+
proc_macro::bridge::client::ProcMacro::Bang { name, client }
57+
if *name == macro_name =>
58+
{
59+
let res = client.run(
60+
&proc_macro::bridge::server::SameThread,
61+
rustc_server::Rustc::default(),
62+
parsed_body,
63+
true,
64+
);
65+
return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
66+
}
67+
proc_macro::bridge::client::ProcMacro::Attr { name, client }
68+
if *name == macro_name =>
69+
{
70+
let res = client.run(
71+
&proc_macro::bridge::server::SameThread,
72+
rustc_server::Rustc::default(),
73+
parsed_attributes,
74+
parsed_body,
75+
true,
76+
);
77+
return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
78+
}
79+
_ => continue,
80+
}
81+
}
82+
83+
Err(proc_macro::bridge::PanicMessage::String("Nothing to expand".to_string()).into())
84+
}
85+
86+
pub fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
87+
self.exported_macros
88+
.iter()
89+
.map(|proc_macro| match proc_macro {
90+
proc_macro::bridge::client::ProcMacro::CustomDerive { trait_name, .. } => {
91+
(trait_name.to_string(), ProcMacroKind::CustomDerive)
92+
}
93+
proc_macro::bridge::client::ProcMacro::Bang { name, .. } => {
94+
(name.to_string(), ProcMacroKind::FuncLike)
95+
}
96+
proc_macro::bridge::client::ProcMacro::Attr { name, .. } => {
97+
(name.to_string(), ProcMacroKind::Attr)
98+
}
99+
})
100+
.collect()
101+
}
102+
}

0 commit comments

Comments
 (0)