Skip to content

Commit a30f167

Browse files
authored
Merge pull request #19985 from ChayimFriedman2/proc-macro-srv-ast-id
fix: Support spans with proc macro servers from before the ast id changes
2 parents 40b743d + af66309 commit a30f167

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)