Skip to content

Commit e240eb6

Browse files
committed
Introduce proc_macro_srv::abis, impl 1.47 and 1.55
Rather than a "Stable" and "Nightly" ABI we instead name ABIs based on the version of the rust compiler in which they were introduced. We place these ABIs in a new module - `proc_macro_srv::abis` - where we also add some mchinery to abstract over ABIs. This should make it easy to add new ABIs at a later date as the rust compiler evolves.
1 parent 14a51d2 commit e240eb6

File tree

28 files changed

+390
-327
lines changed

28 files changed

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

crates/proc_macro_srv/src/proc_macro/bridge/client.rs renamed to crates/proc_macro_srv/src/abis/abi_1_47/proc_macro/bridge/client.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//! Copy from <https://github.com/rust-lang/rust/blob/6050e523bae6de61de4e060facc43dc512adaccd/src/libproc_macro/bridge/client.rs>
44
//! augmented with removing unstable features
55
6+
use super::super::TokenStream as CrateTokenStream;
67
use super::*;
78

89
macro_rules! define_handles {
@@ -401,26 +402,26 @@ fn run_client<A: for<'a, 's> DecodeMut<'a, 's, ()>, R: Encode<()>>(
401402
b
402403
}
403404

404-
impl Client<fn(crate::TokenStream) -> crate::TokenStream> {
405-
pub fn expand1(f: fn(crate::TokenStream) -> crate::TokenStream) -> Self {
405+
impl Client<fn(CrateTokenStream) -> CrateTokenStream> {
406+
pub fn expand1(f: fn(CrateTokenStream) -> CrateTokenStream) -> Self {
406407
extern "C" fn run(
407408
bridge: Bridge<'_>,
408-
f: impl FnOnce(crate::TokenStream) -> crate::TokenStream,
409+
f: impl FnOnce(CrateTokenStream) -> CrateTokenStream,
409410
) -> Buffer<u8> {
410-
run_client(bridge, |input| f(crate::TokenStream(input)).0)
411+
run_client(bridge, |input| f(CrateTokenStream(input)).0)
411412
}
412413
Client { get_handle_counters: HandleCounters::get, run, f }
413414
}
414415
}
415416

416-
impl Client<fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream> {
417-
pub fn expand2(f: fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream) -> Self {
417+
impl Client<fn(CrateTokenStream, CrateTokenStream) -> CrateTokenStream> {
418+
pub fn expand2(f: fn(CrateTokenStream, CrateTokenStream) -> CrateTokenStream) -> Self {
418419
extern "C" fn run(
419420
bridge: Bridge<'_>,
420-
f: impl FnOnce(crate::TokenStream, crate::TokenStream) -> crate::TokenStream,
421+
f: impl FnOnce(CrateTokenStream, CrateTokenStream) -> CrateTokenStream,
421422
) -> Buffer<u8> {
422423
run_client(bridge, |(input, input2)| {
423-
f(crate::TokenStream(input), crate::TokenStream(input2)).0
424+
f(CrateTokenStream(input), CrateTokenStream(input2)).0
424425
})
425426
}
426427
Client { get_handle_counters: HandleCounters::get, run, f }
@@ -433,17 +434,17 @@ pub enum ProcMacro {
433434
CustomDerive {
434435
trait_name: &'static str,
435436
attributes: &'static [&'static str],
436-
client: Client<fn(crate::TokenStream) -> crate::TokenStream>,
437+
client: Client<fn(CrateTokenStream) -> CrateTokenStream>,
437438
},
438439

439440
Attr {
440441
name: &'static str,
441-
client: Client<fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream>,
442+
client: Client<fn(CrateTokenStream, CrateTokenStream) -> CrateTokenStream>,
442443
},
443444

444445
Bang {
445446
name: &'static str,
446-
client: Client<fn(crate::TokenStream) -> crate::TokenStream>,
447+
client: Client<fn(CrateTokenStream) -> CrateTokenStream>,
447448
},
448449
}
449450

@@ -465,19 +466,19 @@ impl ProcMacro {
465466
pub fn custom_derive(
466467
trait_name: &'static str,
467468
attributes: &'static [&'static str],
468-
expand: fn(crate::TokenStream) -> crate::TokenStream,
469+
expand: fn(CrateTokenStream) -> CrateTokenStream,
469470
) -> Self {
470471
ProcMacro::CustomDerive { trait_name, attributes, client: Client::expand1(expand) }
471472
}
472473

473474
pub fn attr(
474475
name: &'static str,
475-
expand: fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream,
476+
expand: fn(CrateTokenStream, CrateTokenStream) -> CrateTokenStream,
476477
) -> Self {
477478
ProcMacro::Attr { name, client: Client::expand2(expand) }
478479
}
479480

480-
pub fn bang(name: &'static str, expand: fn(crate::TokenStream) -> crate::TokenStream) -> Self {
481+
pub fn bang(name: &'static str, expand: fn(CrateTokenStream) -> CrateTokenStream) -> Self {
481482
ProcMacro::Bang { name, client: Client::expand1(expand) }
482483
}
483484
}

crates/proc_macro_srv/src/proc_macro/bridge/mod.rs renamed to crates/proc_macro_srv/src/abis/abi_1_47/proc_macro/bridge/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
1414
#![deny(unsafe_code)]
1515

16-
pub use crate::proc_macro::{Delimiter, Level, LineColumn, Spacing};
16+
pub use super::{Delimiter, Level, LineColumn, Spacing};
1717
use std::fmt;
1818
use std::hash::Hash;
1919
use std::marker;

crates/proc_macro_srv/src/proc_macro/bridge/server.rs renamed to crates/proc_macro_srv/src/abis/abi_1_47/proc_macro/bridge/server.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//! Copy from <https://github.com/rust-lang/rust/blob/6050e523bae6de61de4e060facc43dc512adaccd/src/libproc_macro/bridge/server.rs>
44
//! augmented with removing unstable features
55
6+
use super::super::TokenStream as ProcMacroTokenStream;
67
use super::*;
78

89
// FIXME(eddyb) generate the definition of `HandleStore` in `server.rs`.
@@ -308,7 +309,7 @@ fn run_server<
308309
Result::decode(&mut &b[..], &mut dispatcher.handle_store)
309310
}
310311

311-
impl client::Client<fn(crate::TokenStream) -> crate::TokenStream> {
312+
impl client::Client<fn(ProcMacroTokenStream) -> ProcMacroTokenStream> {
312313
pub fn run<S: Server>(
313314
&self,
314315
strategy: &impl ExecutionStrategy,
@@ -330,7 +331,7 @@ impl client::Client<fn(crate::TokenStream) -> crate::TokenStream> {
330331
}
331332
}
332333

333-
impl client::Client<fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream> {
334+
impl client::Client<fn(ProcMacroTokenStream, ProcMacroTokenStream) -> ProcMacroTokenStream> {
334335
pub fn run<S: Server>(
335336
&self,
336337
strategy: &impl ExecutionStrategy,

crates/proc_macro_srv/src/proc_macro/mod.rs renamed to crates/proc_macro_srv/src/abis/abi_1_47/proc_macro/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl Extend<TokenStream> for TokenStream {
133133

134134
/// Public implementation details for the `TokenStream` type, such as iterators.
135135
pub mod token_stream {
136-
use crate::proc_macro::{bridge, Group, Ident, Literal, Punct, TokenStream, TokenTree};
136+
use super::{bridge, Group, Ident, Literal, Punct, TokenStream, TokenTree};
137137

138138
/// An iterator over `TokenStream`'s `TokenTree`s.
139139
/// The iteration is "shallow", e.g., the iterator doesn't recurse into delimited groups,

crates/proc_macro_srv/src/rustc_server.rs renamed to crates/proc_macro_srv/src/abis/abi_1_47/rustc_server.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
//!
99
//! FIXME: No span and source file information is implemented yet
1010
11-
use crate::proc_macro::bridge::{self, server};
11+
use super::proc_macro::bridge::{self, server};
1212

1313
use std::collections::HashMap;
1414
use std::hash::Hash;
@@ -97,9 +97,9 @@ impl Extend<TokenStream> for TokenStream {
9797
}
9898
}
9999

100-
type Level = crate::proc_macro::Level;
101-
type LineColumn = crate::proc_macro::LineColumn;
102-
type SourceFile = crate::proc_macro::SourceFile;
100+
type Level = super::proc_macro::Level;
101+
type LineColumn = super::proc_macro::LineColumn;
102+
type SourceFile = super::proc_macro::SourceFile;
103103

104104
/// A structure representing a diagnostic message and associated children
105105
/// messages.
@@ -734,8 +734,8 @@ impl server::MultiSpan for Rustc {
734734

735735
#[cfg(test)]
736736
mod tests {
737+
use super::super::proc_macro::bridge::server::Literal;
737738
use super::*;
738-
use crate::proc_macro::bridge::server::Literal;
739739

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

0 commit comments

Comments
 (0)