Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

internal: Encode closing delimiter span in FlatTrees #14572

Merged
merged 1 commit into from Apr 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 6 additions & 3 deletions crates/proc-macro-api/src/lib.rs
Expand Up @@ -146,15 +146,16 @@ impl ProcMacro {
attr: Option<&tt::Subtree>,
env: Vec<(String, String)>,
) -> Result<Result<tt::Subtree, PanicMessage>, ServerError> {
let version = self.process.lock().unwrap_or_else(|e| e.into_inner()).version();
let current_dir = env
.iter()
.find(|(name, _)| name == "CARGO_MANIFEST_DIR")
.map(|(_, value)| value.clone());

let task = ExpandMacro {
macro_body: FlatTree::new(subtree),
macro_body: FlatTree::new(subtree, version),
macro_name: self.name.to_string(),
attributes: attr.map(FlatTree::new),
attributes: attr.map(|subtree| FlatTree::new(subtree, version)),
lib: self.dylib_path.to_path_buf().into(),
env,
current_dir,
Expand All @@ -163,7 +164,9 @@ impl ProcMacro {
let request = msg::Request::ExpandMacro(task);
let response = self.process.lock().unwrap_or_else(|e| e.into_inner()).send_task(request)?;
match response {
msg::Response::ExpandMacro(it) => Ok(it.map(FlatTree::to_subtree)),
msg::Response::ExpandMacro(it) => {
Ok(it.map(|tree| FlatTree::to_subtree(tree, version)))
}
msg::Response::ListMacros(..) | msg::Response::ApiVersionCheck(..) => {
Err(ServerError { message: "unexpected response".to_string(), io: None })
}
Expand Down
10 changes: 7 additions & 3 deletions crates/proc-macro-api/src/msg.rs
Expand Up @@ -12,8 +12,12 @@ use crate::ProcMacroKind;

pub use crate::msg::flat::FlatTree;

// The versions of the server protocol
pub const NO_VERSION_CHECK_VERSION: u32 = 0;
pub const CURRENT_API_VERSION: u32 = 1;
pub const VERSION_CHECK_VERSION: u32 = 1;
pub const ENCODE_CLOSE_SPAN_VERSION: u32 = 2;

pub const CURRENT_API_VERSION: u32 = ENCODE_CLOSE_SPAN_VERSION;

#[derive(Debug, Serialize, Deserialize)]
pub enum Request {
Expand Down Expand Up @@ -146,7 +150,7 @@ mod tests {
fn test_proc_macro_rpc_works() {
let tt = fixture_token_tree();
let task = ExpandMacro {
macro_body: FlatTree::new(&tt),
macro_body: FlatTree::new(&tt, CURRENT_API_VERSION),
macro_name: Default::default(),
attributes: None,
lib: std::env::current_dir().unwrap(),
Expand All @@ -158,6 +162,6 @@ mod tests {
// println!("{}", json);
let back: ExpandMacro = serde_json::from_str(&json).unwrap();

assert_eq!(tt, back.macro_body.to_subtree());
assert_eq!(tt, back.macro_body.to_subtree(CURRENT_API_VERSION));
}
}
60 changes: 44 additions & 16 deletions crates/proc-macro-api/src/msg/flat.rs
Expand Up @@ -39,7 +39,10 @@ use std::collections::{HashMap, VecDeque};

use serde::{Deserialize, Serialize};

use crate::tt::{self, TokenId};
use crate::{
msg::ENCODE_CLOSE_SPAN_VERSION,
tt::{self, TokenId},
};

#[derive(Serialize, Deserialize, Debug)]
pub struct FlatTree {
Expand All @@ -52,7 +55,8 @@ pub struct FlatTree {
}

struct SubtreeRepr {
id: tt::TokenId,
open: tt::TokenId,
close: tt::TokenId,
kind: tt::DelimiterKind,
tt: [u32; 2],
}
Expand All @@ -74,7 +78,7 @@ struct IdentRepr {
}

impl FlatTree {
pub fn new(subtree: &tt::Subtree) -> FlatTree {
pub fn new(subtree: &tt::Subtree, version: u32) -> FlatTree {
let mut w = Writer {
string_table: HashMap::new(),
work: VecDeque::new(),
Expand All @@ -89,7 +93,11 @@ impl FlatTree {
w.write(subtree);

return FlatTree {
subtree: write_vec(w.subtree, SubtreeRepr::write),
subtree: if version >= ENCODE_CLOSE_SPAN_VERSION {
write_vec(w.subtree, SubtreeRepr::write_with_close_span)
} else {
write_vec(w.subtree, SubtreeRepr::write)
},
literal: write_vec(w.literal, LiteralRepr::write),
punct: write_vec(w.punct, PunctRepr::write),
ident: write_vec(w.ident, IdentRepr::write),
Expand All @@ -102,9 +110,13 @@ impl FlatTree {
}
}

pub fn to_subtree(self) -> tt::Subtree {
pub fn to_subtree(self, version: u32) -> tt::Subtree {
return Reader {
subtree: read_vec(self.subtree, SubtreeRepr::read),
subtree: if version >= ENCODE_CLOSE_SPAN_VERSION {
read_vec(self.subtree, SubtreeRepr::read_with_close_span)
} else {
read_vec(self.subtree, SubtreeRepr::read)
},
literal: read_vec(self.literal, LiteralRepr::read),
punct: read_vec(self.punct, PunctRepr::read),
ident: read_vec(self.ident, IdentRepr::read),
Expand All @@ -130,17 +142,36 @@ impl SubtreeRepr {
tt::DelimiterKind::Brace => 2,
tt::DelimiterKind::Bracket => 3,
};
[self.id.0, kind, self.tt[0], self.tt[1]]
[self.open.0, kind, self.tt[0], self.tt[1]]
}
fn read([id, kind, lo, len]: [u32; 4]) -> SubtreeRepr {
fn read([open, kind, lo, len]: [u32; 4]) -> SubtreeRepr {
let kind = match kind {
0 => tt::DelimiterKind::Invisible,
1 => tt::DelimiterKind::Parenthesis,
2 => tt::DelimiterKind::Brace,
3 => tt::DelimiterKind::Bracket,
other => panic!("bad kind {other}"),
};
SubtreeRepr { id: TokenId(id), kind, tt: [lo, len] }
SubtreeRepr { open: TokenId(open), close: TokenId::UNSPECIFIED, kind, tt: [lo, len] }
}
fn write_with_close_span(self) -> [u32; 5] {
let kind = match self.kind {
tt::DelimiterKind::Invisible => 0,
tt::DelimiterKind::Parenthesis => 1,
tt::DelimiterKind::Brace => 2,
tt::DelimiterKind::Bracket => 3,
};
[self.open.0, self.close.0, kind, self.tt[0], self.tt[1]]
}
fn read_with_close_span([open, close, kind, lo, len]: [u32; 5]) -> SubtreeRepr {
let kind = match kind {
0 => tt::DelimiterKind::Invisible,
1 => tt::DelimiterKind::Parenthesis,
2 => tt::DelimiterKind::Brace,
3 => tt::DelimiterKind::Bracket,
other => panic!("bad kind {other}"),
};
SubtreeRepr { open: TokenId(open), close: TokenId(close), kind, tt: [lo, len] }
}
}

Expand Down Expand Up @@ -244,9 +275,10 @@ impl<'a> Writer<'a> {

fn enqueue(&mut self, subtree: &'a tt::Subtree) -> u32 {
let idx = self.subtree.len();
let delimiter_id = subtree.delimiter.open;
let open = subtree.delimiter.open;
let close = subtree.delimiter.close;
let delimiter_kind = subtree.delimiter.kind;
self.subtree.push(SubtreeRepr { id: delimiter_id, kind: delimiter_kind, tt: [!0, !0] });
self.subtree.push(SubtreeRepr { open, close, kind: delimiter_kind, tt: [!0, !0] });
self.work.push_back((idx, subtree));
idx as u32
}
Expand Down Expand Up @@ -277,11 +309,7 @@ impl Reader {
let repr = &self.subtree[i];
let token_trees = &self.token_tree[repr.tt[0] as usize..repr.tt[1] as usize];
let s = tt::Subtree {
delimiter: tt::Delimiter {
open: repr.id,
close: TokenId::UNSPECIFIED,
kind: repr.kind,
},
delimiter: tt::Delimiter { open: repr.open, close: repr.close, kind: repr.kind },
token_trees: token_trees
.iter()
.copied()
Expand Down
4 changes: 4 additions & 0 deletions crates/proc-macro-api/src/process.rs
Expand Up @@ -56,6 +56,10 @@ impl ProcMacroProcessSrv {
}
}

pub(crate) fn version(&self) -> u32 {
self.version
}

pub(crate) fn version_check(&mut self) -> Result<u32, ServerError> {
let request = Request::ApiVersionCheck {};
let response = self.send_task(request)?;
Expand Down
11 changes: 7 additions & 4 deletions crates/proc-macro-srv/src/lib.rs
Expand Up @@ -31,7 +31,10 @@ use std::{
time::SystemTime,
};

use proc_macro_api::{msg, ProcMacroKind};
use proc_macro_api::{
msg::{self, CURRENT_API_VERSION},
ProcMacroKind,
};

use ::tt::token_id as tt;

Expand Down Expand Up @@ -67,16 +70,16 @@ impl ProcMacroSrv {
None => None,
};

let macro_body = task.macro_body.to_subtree();
let attributes = task.attributes.map(|it| it.to_subtree());
let macro_body = task.macro_body.to_subtree(CURRENT_API_VERSION);
let attributes = task.attributes.map(|it| it.to_subtree(CURRENT_API_VERSION));
let result = thread::scope(|s| {
let thread = thread::Builder::new()
.stack_size(EXPANDER_STACK_SIZE)
.name(task.macro_name.clone())
.spawn_scoped(s, || {
expander
.expand(&task.macro_name, &macro_body, attributes.as_ref())
.map(|it| msg::FlatTree::new(&it))
.map(|it| msg::FlatTree::new(&it, CURRENT_API_VERSION))
});
let res = match thread {
Ok(handle) => handle.join(),
Expand Down