Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #13831 - bvanjoi:fix_bound_type_in_trait_insert, r=Veykril
fix(completion): remove bound insert of type in trait Fixed https://github.com/rust-lang/rust-analyzer/issues/13819
bors 2022-12-23
parent 19e5adc · parent 67cbd8f · commit fb0db2a
-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 7384a3f2d8..4a1bacfa9d 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 8ed6cb3cf8..2b10294cc5 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;
+}
+",
+ )
+}