about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/rust-analyzer/Cargo.lock7
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs10
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs5
-rw-r--r--src/tools/rust-analyzer/docs/dev/lsp-extensions.md2
6 files changed, 21 insertions, 6 deletions
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index b6f2c6faf86..8b156a54013 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -85,6 +85,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "base64"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+
+[[package]]
 name = "bitflags"
 version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1649,6 +1655,7 @@ version = "0.0.0"
 dependencies = [
  "always-assert",
  "anyhow",
+ "base64",
  "cargo_metadata",
  "cfg",
  "crossbeam-channel",
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
index 58d871270d9..7c8610280b3 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
@@ -21,6 +21,7 @@ path = "src/bin/main.rs"
 
 [dependencies]
 anyhow.workspace = true
+base64 = "0.22"
 crossbeam-channel.workspace = true
 dirs = "5.0.1"
 dissimilar.workspace = true
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
index 3f2ef7616be..e51b14f6118 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
@@ -10,6 +10,7 @@ use std::{
 
 use anyhow::Context;
 
+use base64::{prelude::BASE64_STANDARD, Engine};
 use ide::{
     AnnotationConfig, AssistKind, AssistResolveStrategy, Cancellable, CompletionFieldsToResolve,
     FilePosition, FileRange, HoverAction, HoverGotoTypeData, InlayFieldsToResolve, Query,
@@ -1136,10 +1137,15 @@ pub(crate) fn handle_completion_resolve(
     else {
         return Ok(original_completion);
     };
+    let Ok(resolve_data_hash) = BASE64_STANDARD.decode(resolve_data.hash) else {
+        return Ok(original_completion);
+    };
 
     let Some(corresponding_completion) = completions.into_iter().find(|completion_item| {
-        let hash = completion_item_hash(completion_item, resolve_data.for_ref);
-        hash == resolve_data.hash
+        // Avoid computing hashes for items that obviously do not match
+        // r-a might append a detail-based suffix to the label, so we cannot check for equality
+        original_completion.label.starts_with(completion_item.label.as_str())
+            && resolve_data_hash == completion_item_hash(completion_item, resolve_data.for_ref)
     }) else {
         return Ok(original_completion);
     };
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs
index afb9c909c68..df06270a8b1 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs
@@ -827,7 +827,7 @@ pub struct CompletionResolveData {
     pub version: Option<i32>,
     pub trigger_character: Option<char>,
     pub for_ref: bool,
-    pub hash: [u8; 20],
+    pub hash: String,
 }
 
 #[derive(Debug, Serialize, Deserialize)]
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs
index a64e1a86210..612cb547b41 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs
@@ -5,6 +5,7 @@ use std::{
     sync::atomic::{AtomicU32, Ordering},
 };
 
+use base64::{prelude::BASE64_STANDARD, Engine};
 use ide::{
     Annotation, AnnotationKind, Assist, AssistKind, Cancellable, CompletionFieldsToResolve,
     CompletionItem, CompletionItemKind, CompletionRelevance, Documentation, FileId, FileRange,
@@ -402,7 +403,7 @@ fn completion_item(
                 version,
                 trigger_character: completion_trigger_character,
                 for_ref: true,
-                hash: completion_item_hash(&item, true),
+                hash: BASE64_STANDARD.encode(completion_item_hash(&item, true)),
             };
             Some(to_value(ref_resolve_data).unwrap())
         } else {
@@ -414,7 +415,7 @@ fn completion_item(
             version,
             trigger_character: completion_trigger_character,
             for_ref: false,
-            hash: completion_item_hash(&item, false),
+            hash: BASE64_STANDARD.encode(completion_item_hash(&item, false)),
         };
         (ref_resolve_data, Some(to_value(resolve_data).unwrap()))
     } else {
diff --git a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
index 80b35d453a3..2aad2cfa361 100644
--- a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
+++ b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
@@ -1,5 +1,5 @@
 <!---
-lsp/ext.rs hash: c4c37ab0bcf7ccb0
+lsp/ext.rs hash: 14b7fb1309f5bb00
 
 If you need to change the above hash to make the test pass, please check if you
 need to adjust this doc as well and ping this issue: