about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-09-19 20:36:09 +0000
committerbors <bors@rust-lang.org>2023-09-19 20:36:09 +0000
commit0427a239eba36a87914dca2c7760f125b6d8fbb0 (patch)
treea984215a5d27fd80029c75a5f60c9390bc50e6a0
parent22b18b9f77eb632b58d207f937b7af42216dd62e (diff)
parentf9fac02c571a4f5520246ab80f5c4b825ca492a5 (diff)
downloadrust-0427a239eba36a87914dca2c7760f125b6d8fbb0.tar.gz
rust-0427a239eba36a87914dca2c7760f125b6d8fbb0.zip
Auto merge of #15635 - SomeoneToIgnore:fix-vscode-edits, r=Veykril
Do not resolve inlayHint.textEdit for VSCode client

Closes https://github.com/rust-lang/rust-analyzer/issues/15604

VSCode behaves strangely, allowing to navigate into label location, but not allowing to apply hint's text edit, after hint is resolved. See https://github.com/microsoft/vscode/issues/193124 for details.

For now, stub hint resolution for VSCode specifically.
-rw-r--r--crates/rust-analyzer/src/bin/main.rs12
-rw-r--r--crates/rust-analyzer/src/config.rs33
-rw-r--r--crates/rust-analyzer/src/diagnostics/to_proto.rs7
-rw-r--r--crates/rust-analyzer/src/lsp/to_proto.rs14
-rw-r--r--crates/rust-analyzer/tests/slow-tests/support.rs1
5 files changed, 49 insertions, 18 deletions
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index 2fa14fc7e28..b8875ef87a4 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -190,6 +190,12 @@ fn run_server() -> anyhow::Result<()> {
         }
     };
 
+    let mut is_visual_studio_code = false;
+    if let Some(client_info) = client_info {
+        tracing::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
+        is_visual_studio_code = client_info.name == "Visual Studio Code";
+    }
+
     let workspace_roots = workspace_folders
         .map(|workspaces| {
             workspaces
@@ -201,7 +207,7 @@ fn run_server() -> anyhow::Result<()> {
         })
         .filter(|workspaces| !workspaces.is_empty())
         .unwrap_or_else(|| vec![root_path.clone()]);
-    let mut config = Config::new(root_path, capabilities, workspace_roots);
+    let mut config = Config::new(root_path, capabilities, workspace_roots, is_visual_studio_code);
     if let Some(json) = initialization_options {
         if let Err(e) = config.update(json) {
             use lsp_types::{
@@ -231,10 +237,6 @@ fn run_server() -> anyhow::Result<()> {
 
     connection.initialize_finish(initialize_id, initialize_result)?;
 
-    if let Some(client_info) = client_info {
-        tracing::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
-    }
-
     if !config.has_linked_projects() && config.detached_files().is_empty() {
         config.rediscover_workspaces();
     }
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index ea3a21241cb..af2a8436efb 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -565,6 +565,7 @@ pub struct Config {
     data: ConfigData,
     detached_files: Vec<AbsPathBuf>,
     snippets: Vec<Snippet>,
+    is_visual_studio_code: bool,
 }
 
 type ParallelCachePrimingNumThreads = u8;
@@ -760,6 +761,7 @@ impl Config {
         root_path: AbsPathBuf,
         caps: ClientCapabilities,
         workspace_roots: Vec<AbsPathBuf>,
+        is_visual_studio_code: bool,
     ) -> Self {
         Config {
             caps,
@@ -769,6 +771,7 @@ impl Config {
             root_path,
             snippets: Default::default(),
             workspace_roots,
+            is_visual_studio_code,
         }
     }
 
@@ -1667,6 +1670,12 @@ impl Config {
     pub fn typing_autoclose_angle(&self) -> bool {
         self.data.typing_autoClosingAngleBrackets_enable
     }
+
+    // FIXME: VSCode seems to work wrong sometimes, see https://github.com/microsoft/vscode/issues/193124
+    // hence, distinguish it for now.
+    pub fn is_visual_studio_code(&self) -> bool {
+        self.is_visual_studio_code
+    }
 }
 // Deserialization definitions
 
@@ -2555,8 +2564,12 @@ mod tests {
 
     #[test]
     fn proc_macro_srv_null() {
-        let mut config =
-            Config::new(AbsPathBuf::try_from(project_root()).unwrap(), Default::default(), vec![]);
+        let mut config = Config::new(
+            AbsPathBuf::try_from(project_root()).unwrap(),
+            Default::default(),
+            vec![],
+            false,
+        );
         config
             .update(serde_json::json!({
                 "procMacro_server": null,
@@ -2567,8 +2580,12 @@ mod tests {
 
     #[test]
     fn proc_macro_srv_abs() {
-        let mut config =
-            Config::new(AbsPathBuf::try_from(project_root()).unwrap(), Default::default(), vec![]);
+        let mut config = Config::new(
+            AbsPathBuf::try_from(project_root()).unwrap(),
+            Default::default(),
+            vec![],
+            false,
+        );
         config
             .update(serde_json::json!({
                 "procMacro": {"server": project_root().display().to_string()}
@@ -2579,8 +2596,12 @@ mod tests {
 
     #[test]
     fn proc_macro_srv_rel() {
-        let mut config =
-            Config::new(AbsPathBuf::try_from(project_root()).unwrap(), Default::default(), vec![]);
+        let mut config = Config::new(
+            AbsPathBuf::try_from(project_root()).unwrap(),
+            Default::default(),
+            vec![],
+            false,
+        );
         config
             .update(serde_json::json!({
                 "procMacro": {"server": "./server"}
diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs
index 731580557c2..f8bc66ff8e7 100644
--- a/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -538,7 +538,12 @@ mod tests {
         let (sender, _) = crossbeam_channel::unbounded();
         let state = GlobalState::new(
             sender,
-            Config::new(workspace_root.to_path_buf(), ClientCapabilities::default(), Vec::new()),
+            Config::new(
+                workspace_root.to_path_buf(),
+                ClientCapabilities::default(),
+                Vec::new(),
+                false,
+            ),
         );
         let snap = state.snapshot();
         let mut actual = map_rust_diagnostic_to_lsp(&config, &diagnostic, workspace_root, &snap);
diff --git a/crates/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs
index 23074493aee..aca91570f7c 100644
--- a/crates/rust-analyzer/src/lsp/to_proto.rs
+++ b/crates/rust-analyzer/src/lsp/to_proto.rs
@@ -443,15 +443,17 @@ pub(crate) fn inlay_hint(
     file_id: FileId,
     inlay_hint: InlayHint,
 ) -> Cancellable<lsp_types::InlayHint> {
+    let is_visual_studio_code = snap.config.is_visual_studio_code();
     let needs_resolve = inlay_hint.needs_resolve;
     let (label, tooltip, mut something_to_resolve) =
         inlay_hint_label(snap, fields_to_resolve, needs_resolve, inlay_hint.label)?;
-    let text_edits = if needs_resolve && fields_to_resolve.resolve_text_edits {
-        something_to_resolve |= inlay_hint.text_edit.is_some();
-        None
-    } else {
-        inlay_hint.text_edit.map(|it| text_edit_vec(line_index, it))
-    };
+    let text_edits =
+        if !is_visual_studio_code && needs_resolve && fields_to_resolve.resolve_text_edits {
+            something_to_resolve |= inlay_hint.text_edit.is_some();
+            None
+        } else {
+            inlay_hint.text_edit.map(|it| text_edit_vec(line_index, it))
+        };
     let data = if needs_resolve && something_to_resolve {
         Some(to_value(lsp_ext::InlayHintResolveData { file_id: file_id.0 }).unwrap())
     } else {
diff --git a/crates/rust-analyzer/tests/slow-tests/support.rs b/crates/rust-analyzer/tests/slow-tests/support.rs
index e49b5768fa4..106b99cb935 100644
--- a/crates/rust-analyzer/tests/slow-tests/support.rs
+++ b/crates/rust-analyzer/tests/slow-tests/support.rs
@@ -150,6 +150,7 @@ impl Project<'_> {
                 ..Default::default()
             },
             roots,
+            false,
         );
         config.update(self.config).expect("invalid config");
         config.rediscover_workspaces();