about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbvanjoi <bohan-zhang@foxmail.com>2022-12-23 17:43:48 +0800
committerbvanjoi <bohan-zhang@foxmail.com>2022-12-23 18:45:25 +0800
commit67cbd8f7c15544cabbaeaeeed9253c9874ed5842 (patch)
tree5f7845b58c122ed818249d653fd25c06388d5250
parenta06525517b0b69cd97f2c39a4012d96f44bf0776 (diff)
downloadrust-67cbd8f7c15544cabbaeaeeed9253c9874ed5842.tar.gz
rust-67cbd8f7c15544cabbaeaeeed9253c9874ed5842.zip
fix(completion): remove bound insert of type in trait
-rw-r--r--crates/ide-completion/src/completions/item_list/trait_impl.rs21
-rw-r--r--crates/ide-completion/src/tests/item_list.rs90
2 files changed, 105 insertions, 6 deletions
diff --git a/crates/ide-completion/src/completions/item_list/trait_impl.rs b/crates/ide-completion/src/completions/item_list/trait_impl.rs
index 7384a3f2d80..4a1bacfa9d9 100644
--- a/crates/ide-completion/src/completions/item_list/trait_impl.rs
+++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs
@@ -37,7 +37,7 @@ use ide_db::{
     traits::get_missing_assoc_items, SymbolKind,
 };
 use syntax::{
-    ast::{self, edit_in_place::AttrsOwnerEdit},
+    ast::{self, edit_in_place::AttrsOwnerEdit, HasTypeBounds},
     AstNode, SyntaxElement, SyntaxKind, TextRange, T,
 };
 use text_edit::TextEdit;
@@ -265,10 +265,21 @@ fn add_type_alias_impl(
             };
 
             let start = transformed_ty.syntax().text_range().start();
-            let Some(end) = transformed_ty
-                .eq_token()
-                .map(|tok| tok.text_range().start())
-                .or(transformed_ty.semicolon_token().map(|tok| tok.text_range().start())) else { return };
+
+            let end = if let Some(end) =
+                transformed_ty.colon_token().map(|tok| tok.text_range().start())
+            {
+                end
+            } else if let Some(end) = transformed_ty.eq_token().map(|tok| tok.text_range().start())
+            {
+                end
+            } else if let Some(end) =
+                transformed_ty.semicolon_token().map(|tok| tok.text_range().start())
+            {
+                end
+            } else {
+                return;
+            };
 
             let len = end - start;
             let mut decl = transformed_ty.syntax().text().slice(..len).to_string();
diff --git a/crates/ide-completion/src/tests/item_list.rs b/crates/ide-completion/src/tests/item_list.rs
index 8ed6cb3cf86..2b10294cc5b 100644
--- a/crates/ide-completion/src/tests/item_list.rs
+++ b/crates/ide-completion/src/tests/item_list.rs
@@ -1,7 +1,7 @@
 //! Completion tests for item list position.
 use expect_test::{expect, Expect};
 
-use crate::tests::{completion_list, BASE_ITEMS_FIXTURE};
+use crate::tests::{check_edit, completion_list, BASE_ITEMS_FIXTURE};
 
 fn check(ra_fixture: &str, expect: Expect) {
     let actual = completion_list(&format!("{}{}", BASE_ITEMS_FIXTURE, ra_fixture));
@@ -277,3 +277,91 @@ fn after_unit_struct() {
         "#]],
     );
 }
+
+#[test]
+fn type_in_impl_trait() {
+    check_edit(
+        "type O",
+        r"
+struct A;
+trait B {
+type O: ?Sized;
+}
+impl B for A {
+$0
+}
+",
+        r#"
+struct A;
+trait B {
+type O: ?Sized;
+}
+impl B for A {
+type O = $0;
+}
+"#,
+    );
+    check_edit(
+        "type O",
+        r"
+struct A;
+trait B {
+type O;
+}
+impl B for A {
+$0
+}
+",
+        r#"
+struct A;
+trait B {
+type O;
+}
+impl B for A {
+type O = $0;
+}
+"#,
+    );
+    check_edit(
+        "type O",
+        r"
+struct A;
+trait B {
+type O: ?Sized = u32;
+}
+impl B for A {
+$0
+}
+",
+        r#"
+struct A;
+trait B {
+type O: ?Sized = u32;
+}
+impl B for A {
+type O = $0;
+}
+"#,
+    );
+    check_edit(
+        "type O",
+        r"
+struct A;
+trait B {
+type O = u32;
+}
+impl B for A {
+$0
+}
+",
+        r"
+struct A;
+trait B {
+type O = u32;
+}
+impl B for A {
+type O = $0;
+}
+",
+    )
+}