From da53a2b22eeaddd70bfccb78f41f222e6f4491b8 Mon Sep 17 00:00:00 2001 From: Michael Barth Date: Thu, 22 Jan 2026 08:06:02 -0500 Subject: [PATCH] lsp: Skip serializing of params if unit type (#46027) Closes #45994 Per the JSON-RPC specification, `params` "MUST be provided as a Structured value" or the member "MAY be omitted." See specification here: https://www.jsonrpc.org/specification#request_object The code was passing in unit `()` for params which serde_json was serializing to `null` which is not valid. This pulls request adds an `is_unit` function and annotates the `params` fields in the `Request` and `Notification` structs with the following: ```rs #[serde(default, skip_serializing_if = "is_unit")] ``` so that the field will be omitted if the type is unit. This does also introduce a `'static` bound to these structs. > [!WARNING] > While this seems to me like a simple change, I am not super familiar with Rust, please look at this PR with extra scrutiny. The last thing I want to do is break everyone's LSP integration. Release Notes: - LSP integrations: send language server shutdown requests with correct parameters --- crates/lsp/src/lsp.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index 519883818c44bdc06b8fa4ac2e3db39d1e14719b..d1ce36c462181544bcf4c4dec26b4e4d3ee9ec2d 100644 --- a/crates/lsp/src/lsp.rs +++ b/crates/lsp/src/lsp.rs @@ -25,6 +25,7 @@ use smol::{ }; use std::{ + any::TypeId, collections::BTreeSet, ffi::{OsStr, OsString}, fmt, @@ -200,14 +201,22 @@ pub enum RequestId { Str(String), } +fn is_unit(_: &T) -> bool { + TypeId::of::() == TypeId::of::<()>() +} + /// Language server protocol RPC request message. /// /// [LSP Specification](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#requestMessage) #[derive(Serialize, Deserialize)] -pub struct Request<'a, T> { +pub struct Request<'a, T> +where + T: 'static, +{ jsonrpc: &'static str, id: RequestId, method: &'a str, + #[serde(default, skip_serializing_if = "is_unit")] params: T, } @@ -245,10 +254,14 @@ enum LspResult { /// /// [LSP Specification](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#notificationMessage) #[derive(Serialize, Deserialize)] -struct Notification<'a, T> { +struct Notification<'a, T> +where + T: 'static, +{ jsonrpc: &'static str, #[serde(borrow)] method: &'a str, + #[serde(default, skip_serializing_if = "is_unit")] params: T, }