Skip to content

Commit af66309

Browse files
Support spans with proc macro servers from before the ast id changes
The only thing changed is the value of the fixup ast id, so we just swap it.
1 parent fa7a6c1 commit af66309

File tree

10 files changed

+96
-102
lines changed

10 files changed

+96
-102
lines changed

src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub enum SpanMode {
5555
Id,
5656

5757
/// Rust Analyzer-specific span handling mode.
58-
RustAnalyzer { fixup_ast_id: u32 },
58+
RustAnalyzer,
5959
}
6060

6161
/// Represents responses sent from the proc-macro-srv to the client.
@@ -308,7 +308,7 @@ mod tests {
308308
#[test]
309309
fn test_proc_macro_rpc_works() {
310310
let tt = fixture_token_tree();
311-
for v in HASHED_AST_ID..=CURRENT_API_VERSION {
311+
for v in RUST_ANALYZER_SPAN_SUPPORT..=CURRENT_API_VERSION {
312312
let mut span_data_table = Default::default();
313313
let task = ExpandMacro {
314314
data: ExpandMacroData {

src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ pub mod legacy_protocol {
1212
mod process;
1313

1414
use paths::{AbsPath, AbsPathBuf};
15-
use span::Span;
15+
use span::{ErasedFileAstId, FIXUP_ERASED_FILE_AST_ID_MARKER, Span};
1616
use std::{fmt, io, sync::Arc, time::SystemTime};
1717

1818
use crate::{
1919
legacy_protocol::msg::{
20-
ExpandMacro, ExpandMacroData, ExpnGlobals, FlatTree, HAS_GLOBAL_SPANS, PanicMessage,
21-
RUST_ANALYZER_SPAN_SUPPORT, Request, Response, SpanDataIndexMap,
20+
ExpandMacro, ExpandMacroData, ExpnGlobals, FlatTree, HAS_GLOBAL_SPANS, HASHED_AST_ID,
21+
PanicMessage, RUST_ANALYZER_SPAN_SUPPORT, Request, Response, SpanDataIndexMap,
2222
deserialize_span_data_index_map, flat::serialize_span_data_index_map,
2323
},
2424
process::ProcMacroServerProcess,
@@ -161,6 +161,38 @@ impl ProcMacro {
161161
self.kind
162162
}
163163

164+
fn needs_fixup_change(&self) -> bool {
165+
let version = self.process.version();
166+
(RUST_ANALYZER_SPAN_SUPPORT..HASHED_AST_ID).contains(&version)
167+
}
168+
169+
/// On some server versions, the fixup ast id is different than ours. So change it to match.
170+
fn change_fixup_to_match_old_server(&self, tt: &mut tt::TopSubtree<Span>) {
171+
const OLD_FIXUP_AST_ID: ErasedFileAstId = ErasedFileAstId::from_raw(!0 - 1);
172+
let change_ast_id = |ast_id: &mut ErasedFileAstId| {
173+
if *ast_id == FIXUP_ERASED_FILE_AST_ID_MARKER {
174+
*ast_id = OLD_FIXUP_AST_ID;
175+
} else if *ast_id == OLD_FIXUP_AST_ID {
176+
// Swap between them, that means no collision plus the change can be reversed by doing itself.
177+
*ast_id = FIXUP_ERASED_FILE_AST_ID_MARKER;
178+
}
179+
};
180+
181+
for tt in &mut tt.0 {
182+
match tt {
183+
tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { span, .. }))
184+
| tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { span, .. }))
185+
| tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { span, .. })) => {
186+
change_ast_id(&mut span.anchor.ast_id);
187+
}
188+
tt::TokenTree::Subtree(subtree) => {
189+
change_ast_id(&mut subtree.delimiter.open.anchor.ast_id);
190+
change_ast_id(&mut subtree.delimiter.close.anchor.ast_id);
191+
}
192+
}
193+
}
194+
}
195+
164196
/// Expands the procedural macro by sending an expansion request to the server.
165197
/// This includes span information and environmental context.
166198
pub fn expand(
@@ -173,6 +205,20 @@ impl ProcMacro {
173205
mixed_site: Span,
174206
current_dir: String,
175207
) -> Result<Result<tt::TopSubtree<Span>, PanicMessage>, ServerError> {
208+
let (mut subtree, mut attr) = (subtree, attr);
209+
let (mut subtree_changed, mut attr_changed);
210+
if self.needs_fixup_change() {
211+
subtree_changed = tt::TopSubtree::from_subtree(subtree);
212+
self.change_fixup_to_match_old_server(&mut subtree_changed);
213+
subtree = subtree_changed.view();
214+
215+
if let Some(attr) = &mut attr {
216+
attr_changed = tt::TopSubtree::from_subtree(*attr);
217+
self.change_fixup_to_match_old_server(&mut attr_changed);
218+
*attr = attr_changed.view();
219+
}
220+
}
221+
176222
let version = self.process.version();
177223

178224
let mut span_data_table = SpanDataIndexMap::default();
@@ -205,15 +251,23 @@ impl ProcMacro {
205251
let response = self.process.send_task(Request::ExpandMacro(Box::new(task)))?;
206252

207253
match response {
208-
Response::ExpandMacro(it) => {
209-
Ok(it.map(|tree| FlatTree::to_subtree_resolved(tree, version, &span_data_table)))
210-
}
254+
Response::ExpandMacro(it) => Ok(it.map(|tree| {
255+
let mut expanded = FlatTree::to_subtree_resolved(tree, version, &span_data_table);
256+
if self.needs_fixup_change() {
257+
self.change_fixup_to_match_old_server(&mut expanded);
258+
}
259+
expanded
260+
})),
211261
Response::ExpandMacroExtended(it) => Ok(it.map(|resp| {
212-
FlatTree::to_subtree_resolved(
262+
let mut expanded = FlatTree::to_subtree_resolved(
213263
resp.tree,
214264
version,
215265
&deserialize_span_data_index_map(&resp.span_data_table),
216-
)
266+
);
267+
if self.needs_fixup_change() {
268+
self.change_fixup_to_match_old_server(&mut expanded);
269+
}
270+
expanded
217271
})),
218272
_ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),
219273
}

src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ use std::{
88
};
99

1010
use paths::AbsPath;
11-
use span::FIXUP_ERASED_FILE_AST_ID_MARKER;
1211
use stdx::JodChild;
1312

1413
use crate::{
1514
ProcMacroKind, ServerError,
1615
legacy_protocol::{
1716
json::{read_json, write_json},
1817
msg::{
19-
CURRENT_API_VERSION, HASHED_AST_ID, Message, Request, Response, ServerConfig, SpanMode,
18+
CURRENT_API_VERSION, Message, RUST_ANALYZER_SPAN_SUPPORT, Request, Response,
19+
ServerConfig, SpanMode,
2020
},
2121
},
2222
};
@@ -71,9 +71,7 @@ impl ProcMacroServerProcess {
7171
Ok(v) => {
7272
tracing::info!("Proc-macro server version: {v}");
7373
srv.version = v;
74-
if srv.version >= HASHED_AST_ID {
75-
// We don't enable spans on versions prior to `HASHED_AST_ID`, because their ast id layout
76-
// is different.
74+
if srv.version >= RUST_ANALYZER_SPAN_SUPPORT {
7775
if let Ok(mode) = srv.enable_rust_analyzer_spans() {
7876
srv.mode = mode;
7977
}
@@ -113,11 +111,7 @@ impl ProcMacroServerProcess {
113111

114112
/// Enable support for rust-analyzer span mode if the server supports it.
115113
fn enable_rust_analyzer_spans(&self) -> Result<SpanMode, ServerError> {
116-
let request = Request::SetConfig(ServerConfig {
117-
span_mode: SpanMode::RustAnalyzer {
118-
fixup_ast_id: FIXUP_ERASED_FILE_AST_ID_MARKER.into_raw(),
119-
},
120-
});
114+
let request = Request::SetConfig(ServerConfig { span_mode: SpanMode::RustAnalyzer });
121115
let response = self.send_task(request)?;
122116

123117
match response {

src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub(crate) fn run() -> io::Result<()> {
2626
let write_response = |msg: msg::Response| msg.write(write_json, &mut io::stdout().lock());
2727

2828
let env = EnvSnapshot::default();
29-
let mut srv = proc_macro_srv::ProcMacroSrv::new(&env);
29+
let srv = proc_macro_srv::ProcMacroSrv::new(&env);
3030

3131
let mut span_mode = SpanMode::Id;
3232

@@ -78,7 +78,7 @@ pub(crate) fn run() -> io::Result<()> {
7878
})
7979
.map_err(msg::PanicMessage)
8080
}),
81-
SpanMode::RustAnalyzer { .. } => msg::Response::ExpandMacroExtended({
81+
SpanMode::RustAnalyzer => msg::Response::ExpandMacroExtended({
8282
let mut span_data_table = deserialize_span_data_index_map(&span_data_table);
8383

8484
let def_site = span_data_table[def_site];
@@ -122,9 +122,6 @@ pub(crate) fn run() -> io::Result<()> {
122122
msg::Request::ApiVersionCheck {} => msg::Response::ApiVersionCheck(CURRENT_API_VERSION),
123123
msg::Request::SetConfig(config) => {
124124
span_mode = config.span_mode;
125-
if let SpanMode::RustAnalyzer { fixup_ast_id } = span_mode {
126-
srv.set_fixup_ast_id(fixup_ast_id);
127-
}
128125
msg::Response::SetConfig(config)
129126
}
130127
};

src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
mod version;
44

55
use proc_macro::bridge;
6-
use span::ErasedFileAstId;
76
use std::{fmt, fs, io, time::SystemTime};
87

98
use libloading::Library;
@@ -162,20 +161,14 @@ impl Expander {
162161
def_site: S,
163162
call_site: S,
164163
mixed_site: S,
165-
fixup_ast_id: ErasedFileAstId,
166164
) -> Result<TopSubtree<S>, String>
167165
where
168166
<S::Server as bridge::server::Types>::TokenStream: Default,
169167
{
170-
let result = self.inner.proc_macros.expand(
171-
macro_name,
172-
macro_body,
173-
attributes,
174-
def_site,
175-
call_site,
176-
mixed_site,
177-
fixup_ast_id,
178-
);
168+
let result = self
169+
.inner
170+
.proc_macros
171+
.expand(macro_name, macro_body, attributes, def_site, call_site, mixed_site);
179172
result.map_err(|e| e.into_string().unwrap_or_default())
180173
}
181174

src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ use std::{
4141
};
4242

4343
use paths::{Utf8Path, Utf8PathBuf};
44-
use span::{ErasedFileAstId, FIXUP_ERASED_FILE_AST_ID_MARKER, Span, TokenId};
44+
use span::{Span, TokenId};
4545

4646
use crate::server_impl::TokenStream;
4747

@@ -57,16 +57,11 @@ pub const RUSTC_VERSION_STRING: &str = env!("RUSTC_VERSION");
5757
pub struct ProcMacroSrv<'env> {
5858
expanders: Mutex<HashMap<Utf8PathBuf, Arc<dylib::Expander>>>,
5959
env: &'env EnvSnapshot,
60-
fixup_ast_id: ErasedFileAstId,
6160
}
6261

6362
impl<'env> ProcMacroSrv<'env> {
6463
pub fn new(env: &'env EnvSnapshot) -> Self {
65-
Self { expanders: Default::default(), env, fixup_ast_id: FIXUP_ERASED_FILE_AST_ID_MARKER }
66-
}
67-
68-
pub fn set_fixup_ast_id(&mut self, fixup_ast_id: u32) {
69-
self.fixup_ast_id = ErasedFileAstId::from_raw(fixup_ast_id);
64+
Self { expanders: Default::default(), env }
7065
}
7166
}
7267

@@ -106,7 +101,6 @@ impl ProcMacroSrv<'_> {
106101
def_site,
107102
call_site,
108103
mixed_site,
109-
self.fixup_ast_id,
110104
)
111105
.map(|tt| tt.0)
112106
});
@@ -162,41 +156,25 @@ impl ProcMacroSrv<'_> {
162156

163157
pub trait ProcMacroSrvSpan: Copy + Send {
164158
type Server: proc_macro::bridge::server::Server<TokenStream = TokenStream<Self>>;
165-
fn make_server(
166-
call_site: Self,
167-
def_site: Self,
168-
mixed_site: Self,
169-
fixup_ast_id: ErasedFileAstId,
170-
) -> Self::Server;
159+
fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server;
171160
}
172161

173162
impl ProcMacroSrvSpan for TokenId {
174163
type Server = server_impl::token_id::TokenIdServer;
175164

176-
fn make_server(
177-
call_site: Self,
178-
def_site: Self,
179-
mixed_site: Self,
180-
_fixup_ast_id: ErasedFileAstId,
181-
) -> Self::Server {
165+
fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server {
182166
Self::Server { call_site, def_site, mixed_site }
183167
}
184168
}
185169
impl ProcMacroSrvSpan for Span {
186170
type Server = server_impl::rust_analyzer_span::RaSpanServer;
187-
fn make_server(
188-
call_site: Self,
189-
def_site: Self,
190-
mixed_site: Self,
191-
fixup_ast_id: ErasedFileAstId,
192-
) -> Self::Server {
171+
fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server {
193172
Self::Server {
194173
call_site,
195174
def_site,
196175
mixed_site,
197176
tracked_env_vars: Default::default(),
198177
tracked_paths: Default::default(),
199-
fixup_ast_id,
200178
}
201179
}
202180
}

src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Proc macro ABI
22
33
use proc_macro::bridge;
4-
use span::ErasedFileAstId;
54

65
use crate::{ProcMacroKind, ProcMacroSrvSpan, server_impl::TopSubtree};
76

@@ -23,7 +22,6 @@ impl ProcMacros {
2322
def_site: S,
2423
call_site: S,
2524
mixed_site: S,
26-
fixup_ast_id: ErasedFileAstId,
2725
) -> Result<TopSubtree<S>, crate::PanicMessage> {
2826
let parsed_body = crate::server_impl::TokenStream::with_subtree(macro_body);
2927

@@ -39,7 +37,7 @@ impl ProcMacros {
3937
{
4038
let res = client.run(
4139
&bridge::server::SameThread,
42-
S::make_server(call_site, def_site, mixed_site, fixup_ast_id),
40+
S::make_server(call_site, def_site, mixed_site),
4341
parsed_body,
4442
cfg!(debug_assertions),
4543
);
@@ -50,7 +48,7 @@ impl ProcMacros {
5048
bridge::client::ProcMacro::Bang { name, client } if *name == macro_name => {
5149
let res = client.run(
5250
&bridge::server::SameThread,
53-
S::make_server(call_site, def_site, mixed_site, fixup_ast_id),
51+
S::make_server(call_site, def_site, mixed_site),
5452
parsed_body,
5553
cfg!(debug_assertions),
5654
);
@@ -61,7 +59,7 @@ impl ProcMacros {
6159
bridge::client::ProcMacro::Attr { name, client } if *name == macro_name => {
6260
let res = client.run(
6361
&bridge::server::SameThread,
64-
S::make_server(call_site, def_site, mixed_site, fixup_ast_id),
62+
S::make_server(call_site, def_site, mixed_site),
6563
parsed_attributes,
6664
parsed_body,
6765
cfg!(debug_assertions),

0 commit comments

Comments
 (0)