Skip to content

Commit aab4fec

Browse files
committed
Auto merge of rust-lang#98188 - mystor:fast_group_punct, r=eddyb
proc_macro/bridge: stop using a remote object handle for proc_macro Punct and Group This is the third part of rust-lang#86822, split off as requested in rust-lang#86822 (review). This patch transforms the `Punct` and `Group` types into structs serialized over IPC rather than handles, making them more efficient to create and manipulate from within proc-macros.
2 parents a4a43ad + acd7a54 commit aab4fec

File tree

4 files changed

+84
-72
lines changed

4 files changed

+84
-72
lines changed

proc_macro/src/bridge/client.rs

-8
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,12 @@ define_handles! {
175175
'owned:
176176
FreeFunctions,
177177
TokenStream,
178-
Group,
179178
Literal,
180179
SourceFile,
181180
MultiSpan,
182181
Diagnostic,
183182

184183
'interned:
185-
Punct,
186184
Ident,
187185
Span,
188186
}
@@ -199,12 +197,6 @@ impl Clone for TokenStream {
199197
}
200198
}
201199

202-
impl Clone for Group {
203-
fn clone(&self) -> Self {
204-
self.clone()
205-
}
206-
}
207-
208200
impl Clone for Literal {
209201
fn clone(&self) -> Self {
210202
self.clone()

proc_macro/src/bridge/mod.rs

+48-32
Original file line numberDiff line numberDiff line change
@@ -65,37 +65,19 @@ macro_rules! with_api {
6565
fn from_str(src: &str) -> $S::TokenStream;
6666
fn to_string($self: &$S::TokenStream) -> String;
6767
fn from_token_tree(
68-
tree: TokenTree<$S::Group, $S::Punct, $S::Ident, $S::Literal>,
68+
tree: TokenTree<$S::TokenStream, $S::Span, $S::Ident, $S::Literal>,
6969
) -> $S::TokenStream;
7070
fn concat_trees(
7171
base: Option<$S::TokenStream>,
72-
trees: Vec<TokenTree<$S::Group, $S::Punct, $S::Ident, $S::Literal>>,
72+
trees: Vec<TokenTree<$S::TokenStream, $S::Span, $S::Ident, $S::Literal>>,
7373
) -> $S::TokenStream;
7474
fn concat_streams(
7575
base: Option<$S::TokenStream>,
7676
streams: Vec<$S::TokenStream>,
7777
) -> $S::TokenStream;
7878
fn into_trees(
7979
$self: $S::TokenStream
80-
) -> Vec<TokenTree<$S::Group, $S::Punct, $S::Ident, $S::Literal>>;
81-
},
82-
Group {
83-
fn drop($self: $S::Group);
84-
fn clone($self: &$S::Group) -> $S::Group;
85-
fn new(delimiter: Delimiter, stream: Option<$S::TokenStream>) -> $S::Group;
86-
fn delimiter($self: &$S::Group) -> Delimiter;
87-
fn stream($self: &$S::Group) -> $S::TokenStream;
88-
fn span($self: &$S::Group) -> $S::Span;
89-
fn span_open($self: &$S::Group) -> $S::Span;
90-
fn span_close($self: &$S::Group) -> $S::Span;
91-
fn set_span($self: &mut $S::Group, span: $S::Span);
92-
},
93-
Punct {
94-
fn new(ch: char, spacing: Spacing) -> $S::Punct;
95-
fn as_char($self: $S::Punct) -> char;
96-
fn spacing($self: $S::Punct) -> Spacing;
97-
fn span($self: $S::Punct) -> $S::Span;
98-
fn with_span($self: $S::Punct, span: $S::Span) -> $S::Punct;
80+
) -> Vec<TokenTree<$S::TokenStream, $S::Span, $S::Ident, $S::Literal>>;
9981
},
10082
Ident {
10183
fn new(string: &str, span: $S::Span, is_raw: bool) -> $S::Ident;
@@ -343,6 +325,7 @@ mark_noop! {
343325
&'_ [u8],
344326
&'_ str,
345327
String,
328+
u8,
346329
usize,
347330
Delimiter,
348331
Level,
@@ -448,16 +431,49 @@ compound_traits!(
448431
}
449432
);
450433

434+
#[derive(Copy, Clone)]
435+
pub struct DelimSpan<Span> {
436+
pub open: Span,
437+
pub close: Span,
438+
pub entire: Span,
439+
}
440+
441+
impl<Span: Copy> DelimSpan<Span> {
442+
pub fn from_single(span: Span) -> Self {
443+
DelimSpan { open: span, close: span, entire: span }
444+
}
445+
}
446+
447+
compound_traits!(struct DelimSpan<Span> { open, close, entire });
448+
449+
#[derive(Clone)]
450+
pub struct Group<TokenStream, Span> {
451+
pub delimiter: Delimiter,
452+
pub stream: Option<TokenStream>,
453+
pub span: DelimSpan<Span>,
454+
}
455+
456+
compound_traits!(struct Group<TokenStream, Span> { delimiter, stream, span });
457+
458+
#[derive(Clone)]
459+
pub struct Punct<Span> {
460+
pub ch: u8,
461+
pub joint: bool,
462+
pub span: Span,
463+
}
464+
465+
compound_traits!(struct Punct<Span> { ch, joint, span });
466+
451467
#[derive(Clone)]
452-
pub enum TokenTree<G, P, I, L> {
453-
Group(G),
454-
Punct(P),
455-
Ident(I),
456-
Literal(L),
468+
pub enum TokenTree<TokenStream, Span, Ident, Literal> {
469+
Group(Group<TokenStream, Span>),
470+
Punct(Punct<Span>),
471+
Ident(Ident),
472+
Literal(Literal),
457473
}
458474

459475
compound_traits!(
460-
enum TokenTree<G, P, I, L> {
476+
enum TokenTree<TokenStream, Span, Ident, Literal> {
461477
Group(tt),
462478
Punct(tt),
463479
Ident(tt),
@@ -468,12 +484,12 @@ compound_traits!(
468484
/// Globals provided alongside the initial inputs for a macro expansion.
469485
/// Provides values such as spans which are used frequently to avoid RPC.
470486
#[derive(Clone)]
471-
pub struct ExpnGlobals<S> {
472-
pub def_site: S,
473-
pub call_site: S,
474-
pub mixed_site: S,
487+
pub struct ExpnGlobals<Span> {
488+
pub def_site: Span,
489+
pub call_site: Span,
490+
pub mixed_site: Span,
475491
}
476492

477493
compound_traits!(
478-
struct ExpnGlobals<Sp> { def_site, call_site, mixed_site }
494+
struct ExpnGlobals<Span> { def_site, call_site, mixed_site }
479495
);

proc_macro/src/bridge/server.rs

-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ use super::client::HandleStore;
88
pub trait Types {
99
type FreeFunctions: 'static;
1010
type TokenStream: 'static + Clone;
11-
type Group: 'static + Clone;
12-
type Punct: 'static + Copy + Eq + Hash;
1311
type Ident: 'static + Copy + Eq + Hash;
1412
type Literal: 'static + Clone;
1513
type SourceFile: 'static + Clone;

proc_macro/src/lib.rs

+36-30
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ pub use quote::{quote, quote_span};
212212
fn tree_to_bridge_tree(
213213
tree: TokenTree,
214214
) -> bridge::TokenTree<
215-
bridge::client::Group,
216-
bridge::client::Punct,
215+
bridge::client::TokenStream,
216+
bridge::client::Span,
217217
bridge::client::Ident,
218218
bridge::client::Literal,
219219
> {
@@ -238,8 +238,8 @@ impl From<TokenTree> for TokenStream {
238238
struct ConcatTreesHelper {
239239
trees: Vec<
240240
bridge::TokenTree<
241-
bridge::client::Group,
242-
bridge::client::Punct,
241+
bridge::client::TokenStream,
242+
bridge::client::Span,
243243
bridge::client::Ident,
244244
bridge::client::Literal,
245245
>,
@@ -365,8 +365,8 @@ pub mod token_stream {
365365
pub struct IntoIter(
366366
std::vec::IntoIter<
367367
bridge::TokenTree<
368-
bridge::client::Group,
369-
bridge::client::Punct,
368+
bridge::client::TokenStream,
369+
bridge::client::Span,
370370
bridge::client::Ident,
371371
bridge::client::Literal,
372372
>,
@@ -788,7 +788,7 @@ impl fmt::Display for TokenTree {
788788
/// A `Group` internally contains a `TokenStream` which is surrounded by `Delimiter`s.
789789
#[derive(Clone)]
790790
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
791-
pub struct Group(bridge::client::Group);
791+
pub struct Group(bridge::Group<bridge::client::TokenStream, bridge::client::Span>);
792792

793793
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
794794
impl !Send for Group {}
@@ -825,13 +825,17 @@ impl Group {
825825
/// method below.
826826
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
827827
pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
828-
Group(bridge::client::Group::new(delimiter, stream.0))
828+
Group(bridge::Group {
829+
delimiter,
830+
stream: stream.0,
831+
span: bridge::DelimSpan::from_single(Span::call_site().0),
832+
})
829833
}
830834

831835
/// Returns the delimiter of this `Group`
832836
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
833837
pub fn delimiter(&self) -> Delimiter {
834-
self.0.delimiter()
838+
self.0.delimiter
835839
}
836840

837841
/// Returns the `TokenStream` of tokens that are delimited in this `Group`.
@@ -840,7 +844,7 @@ impl Group {
840844
/// returned above.
841845
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
842846
pub fn stream(&self) -> TokenStream {
843-
TokenStream(Some(self.0.stream()))
847+
TokenStream(self.0.stream.clone())
844848
}
845849

846850
/// Returns the span for the delimiters of this token stream, spanning the
@@ -852,7 +856,7 @@ impl Group {
852856
/// ```
853857
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
854858
pub fn span(&self) -> Span {
855-
Span(self.0.span())
859+
Span(self.0.span.entire)
856860
}
857861

858862
/// Returns the span pointing to the opening delimiter of this group.
@@ -863,7 +867,7 @@ impl Group {
863867
/// ```
864868
#[stable(feature = "proc_macro_group_span", since = "1.55.0")]
865869
pub fn span_open(&self) -> Span {
866-
Span(self.0.span_open())
870+
Span(self.0.span.open)
867871
}
868872

869873
/// Returns the span pointing to the closing delimiter of this group.
@@ -874,7 +878,7 @@ impl Group {
874878
/// ```
875879
#[stable(feature = "proc_macro_group_span", since = "1.55.0")]
876880
pub fn span_close(&self) -> Span {
877-
Span(self.0.span_close())
881+
Span(self.0.span.close)
878882
}
879883

880884
/// Configures the span for this `Group`'s delimiters, but not its internal
@@ -885,7 +889,7 @@ impl Group {
885889
/// tokens at the level of the `Group`.
886890
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
887891
pub fn set_span(&mut self, span: Span) {
888-
self.0.set_span(span.0);
892+
self.0.span = bridge::DelimSpan::from_single(span.0);
889893
}
890894
}
891895

@@ -925,7 +929,7 @@ impl fmt::Debug for Group {
925929
/// forms of `Spacing` returned.
926930
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
927931
#[derive(Clone)]
928-
pub struct Punct(bridge::client::Punct);
932+
pub struct Punct(bridge::Punct<bridge::client::Span>);
929933

930934
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
931935
impl !Send for Punct {}
@@ -958,13 +962,24 @@ impl Punct {
958962
/// which can be further configured with the `set_span` method below.
959963
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
960964
pub fn new(ch: char, spacing: Spacing) -> Punct {
961-
Punct(bridge::client::Punct::new(ch, spacing))
965+
const LEGAL_CHARS: &[char] = &[
966+
'=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^', '&', '|', '@', '.', ',', ';',
967+
':', '#', '$', '?', '\'',
968+
];
969+
if !LEGAL_CHARS.contains(&ch) {
970+
panic!("unsupported character `{:?}`", ch);
971+
}
972+
Punct(bridge::Punct {
973+
ch: ch as u8,
974+
joint: spacing == Spacing::Joint,
975+
span: Span::call_site().0,
976+
})
962977
}
963978

964979
/// Returns the value of this punctuation character as `char`.
965980
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
966981
pub fn as_char(&self) -> char {
967-
self.0.as_char()
982+
self.0.ch as char
968983
}
969984

970985
/// Returns the spacing of this punctuation character, indicating whether it's immediately
@@ -973,28 +988,19 @@ impl Punct {
973988
/// (`Alone`) so the operator has certainly ended.
974989
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
975990
pub fn spacing(&self) -> Spacing {
976-
self.0.spacing()
991+
if self.0.joint { Spacing::Joint } else { Spacing::Alone }
977992
}
978993

979994
/// Returns the span for this punctuation character.
980995
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
981996
pub fn span(&self) -> Span {
982-
Span(self.0.span())
997+
Span(self.0.span)
983998
}
984999

9851000
/// Configure the span for this punctuation character.
9861001
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
9871002
pub fn set_span(&mut self, span: Span) {
988-
self.0 = self.0.with_span(span.0);
989-
}
990-
}
991-
992-
// N.B., the bridge only provides `to_string`, implement `fmt::Display`
993-
// based on it (the reverse of the usual relationship between the two).
994-
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
995-
impl ToString for Punct {
996-
fn to_string(&self) -> String {
997-
TokenStream::from(TokenTree::from(self.clone())).to_string()
1003+
self.0.span = span.0;
9981004
}
9991005
}
10001006

@@ -1003,7 +1009,7 @@ impl ToString for Punct {
10031009
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
10041010
impl fmt::Display for Punct {
10051011
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1006-
f.write_str(&self.to_string())
1012+
write!(f, "{}", self.as_char())
10071013
}
10081014
}
10091015

0 commit comments

Comments
 (0)