languages: Fix Rust completion labels with fullFunctionSignatures enabled (#59125)

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Closes #57030

When `fullFunctionSignatures` is enabled in `rust-analyzer`, some
completion items returned by the language server have an unexpected
`filterText`. For example:
```jsonc
{
  "label": "sync_all(…)",
  "labelDetails": {
    "detail": "(alias fsync)",
    "description": "pub fn sync_all(&self) -> io::Result<()>"
  },
  "kind": 2,
  "sortText": "7ffffffa",
  "filterText": "sync_allfsync",
  ...
}
```
For such completion items, the rust-analyzer adapter falls back to an
outer range passed into the `mk_label` closure to determine the display
range:

https://github.com/zed-industries/zed/blob/c32c037c6b2b582552edc8c6b9bda513412c3bf4/crates/languages/src/rust.rs#L362-L371

For functions or methods, this fallback range is calculated here:

https://github.com/zed-industries/zed/blob/c32c037c6b2b582552edc8c6b9bda513412c3bf4/crates/languages/src/rust.rs#L424-L435

In this example, the `function_signature` is `"pub fn sync_all(&self) ->
io::Result<()>"`, and the regex matches up to `fn sync_all(&self) ->
io::Result<(`. Currently, the range passed to the `mk_label` closure
mistakenly covers `"ub fn sync_all(&self) -> io::Result<"` (causing the
first character 'p' to be truncated, as reported in #57030), whereas we
only want `"sync_all"` itself

This PR introduces two main changes to fix this behavior:
- Adjust the range start: Skip the leading `fn` keyword so that the
range starts exactly at the function or method name.
- Update the regex pattern: The current pattern matches up to the last
`(`, which causes incorrect slicing if the return type contains
parentheses (e.g., `Result<()>`). This is changed to match up to the
first `(`.

Release Notes:

- Fixed some rust completions has `ub fn ` as prefix when
`fullFunctionSignatures` is enabled
This commit is contained in:
Xin Zhao authored and GitHub committed 2026-06-28 10:08:29 +00:00
1 parent 73b235aeb4
commit afaef857b9
1 file changed
+32 -2
+32 -2
View File
@@ -422,7 +422,7 @@ impl LspAdapter for RustLspAdapter {
};
static FULL_SIGNATURE_REGEX: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"fn (.?+)\(").expect("Failed to create REGEX"));
LazyLock::new(|| Regex::new(r"fn (.+?)\(").expect("Failed to create REGEX"));
if let Some((function_signature, match_)) = function_signature
.filter(|it| it.contains(&label))
.and_then(|it| Some((it, FULL_SIGNATURE_REGEX.find(it)?)))
@@ -431,7 +431,7 @@ impl LspAdapter for RustLspAdapter {
let runs = language.highlight_text(&source, 0..function_signature.len());
mk_label(
function_signature.to_owned(),
&|| match_.range().start - 3..match_.range().end - 1,
&|| match_.range().start + 3..match_.range().end - 1,
runs,
)
} else if let Some((prefix, suffix)) = fn_prefixed {
@@ -1711,6 +1711,36 @@ mod tests {
))
);
assert_eq!(
adapter
.label_for_completion(
&lsp::CompletionItem {
kind: Some(lsp::CompletionItemKind::METHOD),
label: "sync_all(…)".to_string(),
filter_text: Some("sync_allfsync".to_string()),
label_details: Some(CompletionItemLabelDetails {
detail: None,
description: Some(
"pub fn sync_all(&self) -> io::Result<()>".to_string()
),
}),
..Default::default()
},
&language
)
.await,
Some(CodeLabel::new(
"pub fn sync_all(&self) -> io::Result<()>".to_string(),
7..15,
vec![
(0..3, HighlightId::new(1)),
(4..6, HighlightId::new(1)),
(7..15, HighlightId::new(2)),
(30..36, HighlightId::new(0))
],
))
);
assert_eq!(
adapter
.label_for_completion(