Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 2f2cf21

Browse files
committed
Auto merge of rust-lang#15348 - max-heller:issue-14692, r=lowr
Exclude non-identifier aliases from completion filtering text When building `CompletionItem`s, this excludes aliases that aren't valid identifiers from the "lookup" text used to filter completions in the LSP client. Including them results in weird completion filtering behavior e.g. `Partial>` matching a completion for the `PartialOrd` trait because it has a doc alias of ">". Closes rust-lang#14692
2 parents 30f526c + a743903 commit 2f2cf21

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

crates/ide-completion/src/item.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,9 +427,26 @@ impl Builder {
427427
let insert_text = self.insert_text.unwrap_or_else(|| label.to_string());
428428

429429
if !self.doc_aliases.is_empty() {
430-
let doc_aliases = self.doc_aliases.into_iter().join(", ");
430+
let doc_aliases = self.doc_aliases.iter().join(", ");
431431
label = SmolStr::from(format!("{label} (alias {doc_aliases})"));
432-
lookup = SmolStr::from(format!("{lookup} {doc_aliases}"));
432+
let lookup_doc_aliases = self
433+
.doc_aliases
434+
.iter()
435+
// Don't include aliases in `lookup` that aren't valid identifiers as including
436+
// them results in weird completion filtering behavior e.g. `Partial>` matching
437+
// `PartialOrd` because it has an alias of ">".
438+
.filter(|alias| {
439+
let mut chars = alias.chars();
440+
chars.next().is_some_and(char::is_alphabetic)
441+
&& chars.all(|c| c.is_alphanumeric() || c == '_')
442+
})
443+
// Deliberately concatenated without separators as adding separators e.g.
444+
// `alias1, alias2` results in LSP clients continuing to display the completion even
445+
// after typing a comma or space.
446+
.join("");
447+
if !lookup_doc_aliases.is_empty() {
448+
lookup = SmolStr::from(format!("{lookup}{lookup_doc_aliases}"));
449+
}
433450
}
434451
if let [import_edit] = &*self.imports_to_add {
435452
// snippets can have multiple imports, but normal completions only have up to one

crates/ide-completion/src/tests/special.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,3 +1280,26 @@ fn here_we_go() {
12801280
"#]],
12811281
);
12821282
}
1283+
1284+
#[test]
1285+
fn completion_filtering_excludes_non_identifier_doc_aliases() {
1286+
check_edit(
1287+
"PartialOrdcmporder",
1288+
r#"
1289+
#[doc(alias = ">")]
1290+
#[doc(alias = "cmp")]
1291+
#[doc(alias = "order")]
1292+
trait PartialOrd {}
1293+
1294+
struct Foo<T: Partial$0
1295+
"#,
1296+
r#"
1297+
#[doc(alias = ">")]
1298+
#[doc(alias = "cmp")]
1299+
#[doc(alias = "order")]
1300+
trait PartialOrd {}
1301+
1302+
struct Foo<T: PartialOrd
1303+
"#,
1304+
);
1305+
}

0 commit comments

Comments
 (0)