Skip to content

Commit 4f83573

Browse files
committed
proc_macro: stop using a remote object handle for Literal
This builds on the symbol infrastructure built for ident to replicate the `LitKind` and `Lit` structures in rustc within the `proc_macro` client, allowing literals to be fully created and interacted with from the client thread. Only parsing and subspan operations still require sync RPC.
1 parent 11f70c8 commit 4f83573

File tree

6 files changed

+255
-225
lines changed

6 files changed

+255
-225
lines changed

compiler/rustc_expand/src/proc_macro_server.rs

+120-142
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,11 @@ use rustc_session::parse::ParseSess;
1515
use rustc_span::def_id::CrateNum;
1616
use rustc_span::hygiene::ExpnId;
1717
use rustc_span::hygiene::ExpnKind;
18-
use rustc_span::symbol::{self, kw, sym, Symbol};
18+
use rustc_span::symbol::{self, sym, Symbol};
1919
use rustc_span::{BytePos, FileName, MultiSpan, Pos, RealFileName, SourceFile, Span};
2020

21-
use pm::bridge::{server, DelimSpan, Group, Ident, Punct, TokenTree};
21+
use pm::bridge::{server, DelimSpan, Group, Ident, LitKind, Literal, Punct, TokenTree};
2222
use pm::{Delimiter, Level, LineColumn};
23-
use std::ascii;
2423
use std::ops::Bound;
2524

2625
trait FromInternal<T> {
@@ -53,9 +52,40 @@ impl ToInternal<token::DelimToken> for Delimiter {
5352
}
5453
}
5554

56-
impl FromInternal<(TokenStream, &mut Rustc<'_>)>
57-
for Vec<TokenTree<TokenStream, Span, Symbol, Literal>>
58-
{
55+
impl FromInternal<token::LitKind> for LitKind {
56+
fn from_internal(kind: token::LitKind) -> Self {
57+
match kind {
58+
token::Byte => LitKind::Byte,
59+
token::Char => LitKind::Char,
60+
token::Integer => LitKind::Integer,
61+
token::Float => LitKind::Float,
62+
token::Str => LitKind::Str,
63+
token::StrRaw(n) => LitKind::StrRaw(n),
64+
token::ByteStr => LitKind::ByteStr,
65+
token::ByteStrRaw(n) => LitKind::ByteStrRaw(n),
66+
token::Err => LitKind::Err,
67+
token::Bool => unreachable!(),
68+
}
69+
}
70+
}
71+
72+
impl ToInternal<token::LitKind> for LitKind {
73+
fn to_internal(self) -> token::LitKind {
74+
match self {
75+
LitKind::Byte => token::Byte,
76+
LitKind::Char => token::Char,
77+
LitKind::Integer => token::Integer,
78+
LitKind::Float => token::Float,
79+
LitKind::Str => token::Str,
80+
LitKind::StrRaw(n) => token::StrRaw(n),
81+
LitKind::ByteStr => token::ByteStr,
82+
LitKind::ByteStrRaw(n) => token::ByteStrRaw(n),
83+
LitKind::Err => token::Err,
84+
}
85+
}
86+
}
87+
88+
impl FromInternal<(TokenStream, &mut Rustc<'_>)> for Vec<TokenTree<TokenStream, Span, Symbol>> {
5989
fn from_internal((stream, rustc): (TokenStream, &mut Rustc<'_>)) -> Self {
6090
use rustc_ast::token::*;
6191

@@ -162,7 +192,9 @@ impl FromInternal<(TokenStream, &mut Rustc<'_>)>
162192
tt!(Punct { ch: '\'', joint: true });
163193
tt!(Ident { sym: ident.name, is_raw: false });
164194
}
165-
Literal(lit) => tt!(Literal { lit }),
195+
Literal(token::Lit { kind, symbol, suffix }) => {
196+
tt!(Literal { kind: FromInternal::from_internal(kind), symbol, suffix });
197+
}
166198
DocComment(_, attr_style, data) => {
167199
let mut escaped = String::new();
168200
for ch in data.as_str().chars() {
@@ -217,7 +249,7 @@ impl FromInternal<(TokenStream, &mut Rustc<'_>)>
217249
}
218250
}
219251

220-
impl ToInternal<TokenStream> for TokenTree<TokenStream, Span, Symbol, Literal> {
252+
impl ToInternal<TokenStream> for TokenTree<TokenStream, Span, Symbol> {
221253
fn to_internal(self) -> TokenStream {
222254
use rustc_ast::token::*;
223255

@@ -235,7 +267,9 @@ impl ToInternal<TokenStream> for TokenTree<TokenStream, Span, Symbol, Literal> {
235267
return tokenstream::TokenTree::token(Ident(sym, is_raw), span).into();
236268
}
237269
TokenTree::Literal(self::Literal {
238-
lit: token::Lit { kind: token::Integer, symbol, suffix },
270+
kind: self::LitKind::Integer,
271+
symbol,
272+
suffix,
239273
span,
240274
}) if symbol.as_str().starts_with('-') => {
241275
let minus = BinOp(BinOpToken::Minus);
@@ -246,7 +280,9 @@ impl ToInternal<TokenStream> for TokenTree<TokenStream, Span, Symbol, Literal> {
246280
return vec![a, b].into_iter().collect();
247281
}
248282
TokenTree::Literal(self::Literal {
249-
lit: token::Lit { kind: token::Float, symbol, suffix },
283+
kind: self::LitKind::Float,
284+
symbol,
285+
suffix,
250286
span,
251287
}) if symbol.as_str().starts_with('-') => {
252288
let minus = BinOp(BinOpToken::Minus);
@@ -256,8 +292,12 @@ impl ToInternal<TokenStream> for TokenTree<TokenStream, Span, Symbol, Literal> {
256292
let b = tokenstream::TokenTree::token(float, span);
257293
return vec![a, b].into_iter().collect();
258294
}
259-
TokenTree::Literal(self::Literal { lit, span }) => {
260-
return tokenstream::TokenTree::token(Literal(lit), span).into();
295+
TokenTree::Literal(self::Literal { kind, symbol, suffix, span }) => {
296+
return tokenstream::TokenTree::token(
297+
TokenKind::lit(kind.to_internal(), symbol, suffix),
298+
span,
299+
)
300+
.into();
261301
}
262302
};
263303

@@ -306,13 +346,6 @@ impl ToInternal<rustc_errors::Level> for Level {
306346

307347
pub struct FreeFunctions;
308348

309-
// FIXME(eddyb) `Literal` should not expose internal `Debug` impls.
310-
#[derive(Clone, Debug)]
311-
pub struct Literal {
312-
lit: token::Lit,
313-
span: Span,
314-
}
315-
316349
pub(crate) struct Rustc<'a> {
317350
resolver: &'a dyn ResolverExpand,
318351
sess: &'a ParseSess,
@@ -344,19 +377,11 @@ impl<'a> Rustc<'a> {
344377
rebased_spans: FxHashMap::default(),
345378
}
346379
}
347-
348-
fn lit(&mut self, kind: token::LitKind, symbol: Symbol, suffix: Option<Symbol>) -> Literal {
349-
Literal {
350-
lit: token::Lit::new(kind, symbol, suffix),
351-
span: server::Context::call_site(self),
352-
}
353-
}
354380
}
355381

356382
impl server::Types for Rustc<'_> {
357383
type FreeFunctions = FreeFunctions;
358384
type TokenStream = TokenStream;
359-
type Literal = Literal;
360385
type SourceFile = Lrc<SourceFile>;
361386
type MultiSpan = Vec<Span>;
362387
type Diagnostic = Diagnostic;
@@ -368,67 +393,8 @@ impl server::FreeFunctions for Rustc<'_> {
368393
fn track_env_var(&mut self, var: &str, value: Option<&str>) {
369394
self.sess.env_depinfo.borrow_mut().insert((Symbol::intern(var), value.map(Symbol::intern)));
370395
}
371-
}
372-
373-
impl server::TokenStream for Rustc<'_> {
374-
fn is_empty(&mut self, stream: &Self::TokenStream) -> bool {
375-
stream.is_empty()
376-
}
377-
fn from_str(&mut self, src: &str) -> Self::TokenStream {
378-
parse_stream_from_source_str(
379-
FileName::proc_macro_source_code(src),
380-
src.to_string(),
381-
self.sess,
382-
Some(self.call_site),
383-
)
384-
}
385-
fn to_string(&mut self, stream: &Self::TokenStream) -> String {
386-
pprust::tts_to_string(stream)
387-
}
388-
fn from_token_tree(
389-
&mut self,
390-
tree: TokenTree<Self::TokenStream, Self::Span, Self::Symbol, Self::Literal>,
391-
) -> Self::TokenStream {
392-
tree.to_internal()
393-
}
394-
fn concat_trees(
395-
&mut self,
396-
base: Option<Self::TokenStream>,
397-
trees: Vec<TokenTree<Self::TokenStream, Self::Span, Self::Symbol, Self::Literal>>,
398-
) -> Self::TokenStream {
399-
let mut builder = tokenstream::TokenStreamBuilder::new();
400-
if let Some(base) = base {
401-
builder.push(base);
402-
}
403-
for tree in trees {
404-
builder.push(tree.to_internal());
405-
}
406-
builder.build()
407-
}
408-
fn concat_streams(
409-
&mut self,
410-
base: Option<Self::TokenStream>,
411-
streams: Vec<Self::TokenStream>,
412-
) -> Self::TokenStream {
413-
let mut builder = tokenstream::TokenStreamBuilder::new();
414-
if let Some(base) = base {
415-
builder.push(base);
416-
}
417-
for stream in streams {
418-
builder.push(stream);
419-
}
420-
builder.build()
421-
}
422-
fn into_iter(
423-
&mut self,
424-
stream: Self::TokenStream,
425-
) -> Vec<TokenTree<Self::TokenStream, Self::Span, Self::Symbol, Self::Literal>> {
426-
FromInternal::from_internal((stream, self))
427-
}
428-
}
429396

430-
impl server::Literal for Rustc<'_> {
431-
fn from_str(&mut self, s: &str) -> Result<Self::Literal, ()> {
397+
fn literal_from_str(&mut self, s: &str) -> Result<Literal<Self::Span, Self::Symbol>, ()> {
432398
let override_span = None;
433399
let stream = parse_stream_from_source_str(
434400
FileName::proc_macro_source_code(s),
@@ -449,66 +415,21 @@ impl server::Literal for Rustc<'_> {
449415
// There is a comment or whitespace adjacent to the literal.
450416
return Err(());
451417
}
452-
let lit = match token.kind {
418+
let token::Lit { kind, symbol, suffix } = match token.kind {
453419
TokenKind::Literal(lit) => lit,
454420
_ => return Err(()),
455421
};
456-
Ok(Literal { lit, span: self.call_site })
457-
}
458-
fn debug_kind(&mut self, literal: &Self::Literal) -> String {
459-
format!("{:?}", literal.lit.kind)
460-
}
461-
fn symbol(&mut self, literal: &Self::Literal) -> String {
462-
literal.lit.symbol.to_string()
463-
}
464-
fn suffix(&mut self, literal: &Self::Literal) -> Option<String> {
465-
literal.lit.suffix.as_ref().map(Symbol::to_string)
466-
}
467-
fn integer(&mut self, n: &str) -> Self::Literal {
468-
self.lit(token::Integer, Symbol::intern(n), None)
469-
}
470-
fn typed_integer(&mut self, n: &str, kind: &str) -> Self::Literal {
471-
self.lit(token::Integer, Symbol::intern(n), Some(Symbol::intern(kind)))
472-
}
473-
fn float(&mut self, n: &str) -> Self::Literal {
474-
self.lit(token::Float, Symbol::intern(n), None)
475-
}
476-
fn f32(&mut self, n: &str) -> Self::Literal {
477-
self.lit(token::Float, Symbol::intern(n), Some(sym::f32))
478-
}
479-
fn f64(&mut self, n: &str) -> Self::Literal {
480-
self.lit(token::Float, Symbol::intern(n), Some(sym::f64))
481-
}
482-
fn string(&mut self, string: &str) -> Self::Literal {
483-
let mut escaped = String::new();
484-
for ch in string.chars() {
485-
escaped.extend(ch.escape_debug());
486-
}
487-
self.lit(token::Str, Symbol::intern(&escaped), None)
488-
}
489-
fn character(&mut self, ch: char) -> Self::Literal {
490-
let mut escaped = String::new();
491-
escaped.extend(ch.escape_unicode());
492-
self.lit(token::Char, Symbol::intern(&escaped), None)
493-
}
494-
fn byte_string(&mut self, bytes: &[u8]) -> Self::Literal {
495-
let string = bytes
496-
.iter()
497-
.cloned()
498-
.flat_map(ascii::escape_default)
499-
.map(Into::<char>::into)
500-
.collect::<String>();
501-
self.lit(token::ByteStr, Symbol::intern(&string), None)
502-
}
503-
fn span(&mut self, literal: &Self::Literal) -> Self::Span {
504-
literal.span
505-
}
506-
fn set_span(&mut self, literal: &mut Self::Literal, span: Self::Span) {
507-
literal.span = span;
422+
Ok(Literal {
423+
kind: FromInternal::from_internal(kind),
424+
symbol,
425+
suffix,
426+
span: self.call_site,
427+
})
508428
}
509-
fn subspan(
429+
430+
fn literal_subspan(
510431
&mut self,
511-
literal: &Self::Literal,
432+
literal: Literal<Self::Span, Self::Symbol>,
512433
start: Bound<usize>,
513434
end: Bound<usize>,
514435
) -> Option<Self::Span> {
@@ -544,6 +465,63 @@ impl server::Literal for Rustc<'_> {
544465
}
545466
}
546467

468+
impl server::TokenStream for Rustc<'_> {
469+
fn is_empty(&mut self, stream: &Self::TokenStream) -> bool {
470+
stream.is_empty()
471+
}
472+
fn from_str(&mut self, src: &str) -> Self::TokenStream {
473+
parse_stream_from_source_str(
474+
FileName::proc_macro_source_code(src),
475+
src.to_string(),
476+
self.sess,
477+
Some(self.call_site),
478+
)
479+
}
480+
fn to_string(&mut self, stream: &Self::TokenStream) -> String {
481+
pprust::tts_to_string(stream)
482+
}
483+
fn from_token_tree(
484+
&mut self,
485+
tree: TokenTree<Self::TokenStream, Self::Span, Self::Symbol>,
486+
) -> Self::TokenStream {
487+
tree.to_internal()
488+
}
489+
fn concat_trees(
490+
&mut self,
491+
base: Option<Self::TokenStream>,
492+
trees: Vec<TokenTree<Self::TokenStream, Self::Span, Self::Symbol>>,
493+
) -> Self::TokenStream {
494+
let mut builder = tokenstream::TokenStreamBuilder::new();
495+
if let Some(base) = base {
496+
builder.push(base);
497+
}
498+
for tree in trees {
499+
builder.push(tree.to_internal());
500+
}
501+
builder.build()
502+
}
503+
fn concat_streams(
504+
&mut self,
505+
base: Option<Self::TokenStream>,
506+
streams: Vec<Self::TokenStream>,
507+
) -> Self::TokenStream {
508+
let mut builder = tokenstream::TokenStreamBuilder::new();
509+
if let Some(base) = base {
510+
builder.push(base);
511+
}
512+
for stream in streams {
513+
builder.push(stream);
514+
}
515+
builder.build()
516+
}
517+
fn into_iter(
518+
&mut self,
519+
stream: Self::TokenStream,
520+
) -> Vec<TokenTree<Self::TokenStream, Self::Span, Self::Symbol>> {
521+
FromInternal::from_internal((stream, self))
522+
}
523+
}
524+
547525
impl server::SourceFile for Rustc<'_> {
548526
fn eq(&mut self, file1: &Self::SourceFile, file2: &Self::SourceFile) -> bool {
549527
Lrc::ptr_eq(file1, file2)

0 commit comments

Comments
 (0)