internal: Ensure proc-macro-api version check works with postcard across protocol versions

This commit is contained in:
Lukas Wirth 2025-11-29 20:54:34 +01:00
parent 2d3f2e516f
commit f8a7fd5a4d
4 changed files with 39 additions and 14 deletions

View File

@ -161,11 +161,12 @@ pub enum GenericRequirement {
macro_rules! language_item_table {
(
$LangItems:ident =>
$( $(#[$attr:meta])* $lang_item:ident, $module:ident :: $name:ident, $method:ident, $target:ident, $generics:expr; )*
) => {
#[allow(non_snake_case)] // FIXME: Should we remove this?
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
pub struct LangItems {
pub struct $LangItems {
$(
$(#[$attr])*
pub $lang_item: Option<$target>,
@ -219,7 +220,7 @@ macro_rules! language_item_table {
}
}
language_item_table! {
language_item_table! { LangItems =>
// Variant name, Name, Getter method name, Target Generic requirements;
Sized, sym::sized, sized_trait, TraitId, GenericRequirement::Exact(0);
MetaSized, sym::meta_sized, sized_trait, TraitId, GenericRequirement::Exact(0);

View File

@ -13,6 +13,13 @@ use crate::{ProcMacroKind, codec::Codec};
/// Represents requests sent from the client to the proc-macro-srv.
#[derive(Debug, Serialize, Deserialize)]
pub enum Request {
// IMPORTANT: Keep his first, otherwise postcard will break as its not a self describing format
// As such, this is the only request that needs to be supported across all protocol versions
// and by keeping it first, we ensure it always has the same discriminant encoding in postcard
/// Performs an API version check between the client and the server.
/// Since [`VERSION_CHECK_VERSION`]
ApiVersionCheck {},
/// Retrieves a list of macros from a given dynamic library.
/// Since [`NO_VERSION_CHECK_VERSION`]
ListMacros { dylib_path: Utf8PathBuf },
@ -21,10 +28,6 @@ pub enum Request {
/// Since [`NO_VERSION_CHECK_VERSION`]
ExpandMacro(Box<ExpandMacro>),
/// Performs an API version check between the client and the server.
/// Since [`VERSION_CHECK_VERSION`]
ApiVersionCheck {},
/// Sets server-specific configurations.
/// Since [`RUST_ANALYZER_SPAN_SUPPORT`]
SetConfig(ServerConfig),
@ -44,6 +47,13 @@ pub enum SpanMode {
/// Represents responses sent from the proc-macro-srv to the client.
#[derive(Debug, Serialize, Deserialize)]
pub enum Response {
// IMPORTANT: Keep his first, otherwise postcard will break as its not a self describing format
// As such, this is the only request that needs to be supported across all protocol versions
// and by keeping it first, we ensure it always has the same discriminant encoding in postcard
/// Returns the API version supported by the server.
/// Since [`NO_VERSION_CHECK_VERSION`]
ApiVersionCheck(u32),
/// Returns a list of available macros in a dynamic library.
/// Since [`NO_VERSION_CHECK_VERSION`]
ListMacros(Result<Vec<(String, ProcMacroKind)>, String>),
@ -52,10 +62,6 @@ pub enum Response {
/// Since [`NO_VERSION_CHECK_VERSION`]
ExpandMacro(Result<FlatTree, PanicMessage>),
/// Returns the API version supported by the server.
/// Since [`NO_VERSION_CHECK_VERSION`]
ApiVersionCheck(u32),
/// Confirms the application of a configuration update.
/// Since [`RUST_ANALYZER_SPAN_SUPPORT`]
SetConfig(ServerConfig),

View File

@ -198,7 +198,13 @@ impl ProcMacroSrvSpan for SpanId {
type Server = server_impl::token_id::SpanIdServer;
fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server {
Self::Server { call_site, def_site, mixed_site }
Self::Server {
call_site,
def_site,
mixed_site,
tracked_env_vars: Default::default(),
tracked_paths: Default::default(),
}
}
}
impl ProcMacroSrvSpan for Span {

View File

@ -1,6 +1,9 @@
//! proc-macro server backend based on [`proc_macro_api::msg::SpanId`] as the backing span.
//! This backend is rather inflexible, used by RustRover and older rust-analyzer versions.
use std::ops::{Bound, Range};
use std::{
collections::{HashMap, HashSet},
ops::{Bound, Range},
};
use intern::Symbol;
use proc_macro::bridge::server;
@ -24,6 +27,10 @@ type Span = SpanId;
pub struct FreeFunctions;
pub struct SpanIdServer {
// FIXME: Report this back to the caller to track as dependencies
pub tracked_env_vars: HashMap<Box<str>, Option<Box<str>>>,
// FIXME: Report this back to the caller to track as dependencies
pub tracked_paths: HashSet<Box<str>>,
pub call_site: Span,
pub def_site: Span,
pub mixed_site: Span,
@ -40,8 +47,13 @@ impl server::FreeFunctions for SpanIdServer {
fn injected_env_var(&mut self, _: &str) -> Option<std::string::String> {
None
}
fn track_env_var(&mut self, _var: &str, _value: Option<&str>) {}
fn track_path(&mut self, _path: &str) {}
fn track_env_var(&mut self, var: &str, value: Option<&str>) {
self.tracked_env_vars.insert(var.into(), value.map(Into::into));
}
fn track_path(&mut self, path: &str) {
self.tracked_paths.insert(path.into());
}
fn literal_from_str(&mut self, s: &str) -> Result<Literal<Self::Span>, ()> {
literal_from_str(s, self.call_site)
}