summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/ide-completion
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:32 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:32 +0000
commit4547b622d8d29df964fa2914213088b148c498fc (patch)
tree9fc6b25f3c3add6b745be9a2400a6e96140046e9 /src/tools/rust-analyzer/crates/ide-completion
parentReleasing progress-linux version 1.66.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-4547b622d8d29df964fa2914213088b148c498fc.tar.xz
rustc-4547b622d8d29df964fa2914213088b148c498fc.zip
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tools/rust-analyzer/crates/ide-completion')
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs159
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs29
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs32
5 files changed, 203 insertions, 27 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml b/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml
index 75835bce9..11310e2f1 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs
index e82cbfdcb..7384a3f2d 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs
@@ -157,7 +157,7 @@ fn complete_trait_impl(
add_function_impl(acc, ctx, replacement_range, func, hir_impl)
}
(hir::AssocItem::TypeAlias(type_alias), All | TypeAlias) => {
- add_type_alias_impl(acc, ctx, replacement_range, type_alias)
+ add_type_alias_impl(acc, ctx, replacement_range, type_alias, hir_impl)
}
(hir::AssocItem::Const(const_), All | Const) => {
add_const_impl(acc, ctx, replacement_range, const_, hir_impl)
@@ -236,9 +236,7 @@ fn get_transformed_assoc_item(
);
transform.apply(assoc_item.syntax());
- if let ast::AssocItem::Fn(func) = &assoc_item {
- func.remove_attrs_and_docs();
- }
+ assoc_item.remove_attrs_and_docs();
Some(assoc_item)
}
@@ -247,24 +245,50 @@ fn add_type_alias_impl(
ctx: &CompletionContext<'_>,
replacement_range: TextRange,
type_alias: hir::TypeAlias,
+ impl_def: hir::Impl,
) {
- let alias_name = type_alias.name(ctx.db);
- let (alias_name, escaped_name) =
- (alias_name.unescaped().to_smol_str(), alias_name.to_smol_str());
+ let alias_name = type_alias.name(ctx.db).unescaped().to_smol_str();
let label = format!("type {} =", alias_name);
- let replacement = format!("type {} = ", escaped_name);
let mut item = CompletionItem::new(SymbolKind::TypeAlias, replacement_range, label);
item.lookup_by(format!("type {}", alias_name))
.set_documentation(type_alias.docs(ctx.db))
.set_relevance(CompletionRelevance { is_item_from_trait: true, ..Default::default() });
- match ctx.config.snippet_cap {
- Some(cap) => item
- .snippet_edit(cap, TextEdit::replace(replacement_range, format!("{}$0;", replacement))),
- None => item.text_edit(TextEdit::replace(replacement_range, replacement)),
- };
- item.add_to(acc);
+
+ if let Some(source) = ctx.sema.source(type_alias) {
+ let assoc_item = ast::AssocItem::TypeAlias(source.value);
+ if let Some(transformed_item) = get_transformed_assoc_item(ctx, assoc_item, impl_def) {
+ let transformed_ty = match transformed_item {
+ ast::AssocItem::TypeAlias(ty) => ty,
+ _ => unreachable!(),
+ };
+
+ 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 len = end - start;
+ let mut decl = transformed_ty.syntax().text().slice(..len).to_string();
+ if !decl.ends_with(' ') {
+ decl.push(' ');
+ }
+ decl.push_str("= ");
+
+ match ctx.config.snippet_cap {
+ Some(cap) => {
+ let snippet = format!("{}$0;", decl);
+ item.snippet_edit(cap, TextEdit::replace(replacement_range, snippet));
+ }
+ None => {
+ item.text_edit(TextEdit::replace(replacement_range, decl));
+ }
+ };
+ item.add_to(acc);
+ }
+ }
}
fn add_const_impl(
@@ -309,7 +333,6 @@ fn add_const_impl(
}
fn make_const_compl_syntax(const_: &ast::Const, needs_whitespace: bool) -> String {
- const_.remove_attrs_and_docs();
let const_ = if needs_whitespace {
insert_whitespace_into_node::insert_ws_into(const_.syntax().clone())
} else {
@@ -333,8 +356,6 @@ fn make_const_compl_syntax(const_: &ast::Const, needs_whitespace: bool) -> Strin
}
fn function_declaration(node: &ast::Fn, needs_whitespace: bool) -> String {
- node.remove_attrs_and_docs();
-
let node = if needs_whitespace {
insert_whitespace_into_node::insert_ws_into(node.syntax().clone())
} else {
@@ -350,9 +371,7 @@ fn function_declaration(node: &ast::Fn, needs_whitespace: bool) -> String {
.map_or(end, |f| f.text_range().start());
let len = end - start;
- let range = TextRange::new(0.into(), len);
-
- let syntax = node.text().slice(range).to_string();
+ let syntax = node.text().slice(..len).to_string();
syntax.trim_end().to_owned()
}
@@ -1163,4 +1182,104 @@ impl Foo for Test {
"#,
);
}
+
+ #[test]
+ fn includes_gat_generics() {
+ check_edit(
+ "type Ty",
+ r#"
+trait Tr<'b> {
+ type Ty<'a: 'b, T: Copy, const C: usize>;
+}
+
+impl<'b> Tr<'b> for () {
+ $0
+}
+"#,
+ r#"
+trait Tr<'b> {
+ type Ty<'a: 'b, T: Copy, const C: usize>;
+}
+
+impl<'b> Tr<'b> for () {
+ type Ty<'a: 'b, T: Copy, const C: usize> = $0;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn strips_comments() {
+ check_edit(
+ "fn func",
+ r#"
+trait Tr {
+ /// docs
+ #[attr]
+ fn func();
+}
+impl Tr for () {
+ $0
+}
+"#,
+ r#"
+trait Tr {
+ /// docs
+ #[attr]
+ fn func();
+}
+impl Tr for () {
+ fn func() {
+ $0
+}
+}
+"#,
+ );
+ check_edit(
+ "const C",
+ r#"
+trait Tr {
+ /// docs
+ #[attr]
+ const C: usize;
+}
+impl Tr for () {
+ $0
+}
+"#,
+ r#"
+trait Tr {
+ /// docs
+ #[attr]
+ const C: usize;
+}
+impl Tr for () {
+ const C: usize = $0;
+}
+"#,
+ );
+ check_edit(
+ "type Item",
+ r#"
+trait Tr {
+ /// docs
+ #[attr]
+ type Item;
+}
+impl Tr for () {
+ $0
+}
+"#,
+ r#"
+trait Tr {
+ /// docs
+ #[attr]
+ type Item;
+}
+impl Tr for () {
+ type Item = $0;
+}
+"#,
+ );
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
index 9a891cea2..b9bd47f7d 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
@@ -69,10 +69,6 @@ pub(crate) fn complete_postfix(
}
}
- if !ctx.config.snippets.is_empty() {
- add_custom_postfix_completions(acc, ctx, &postfix_snippet, &receiver_text);
- }
-
let try_enum = TryEnum::from_ty(&ctx.sema, &receiver_ty.strip_references());
if let Some(try_enum) = &try_enum {
match try_enum {
@@ -140,6 +136,10 @@ pub(crate) fn complete_postfix(
None => return,
};
+ if !ctx.config.snippets.is_empty() {
+ add_custom_postfix_completions(acc, ctx, &postfix_snippet, &receiver_text);
+ }
+
match try_enum {
Some(try_enum) => match try_enum {
TryEnum::Result => {
@@ -613,4 +613,25 @@ fn main() {
r#"fn main() { log::error!("{}", 2+2) }"#,
);
}
+
+ #[test]
+ fn postfix_custom_snippets_completion_for_references() {
+ check_edit_with_config(
+ CompletionConfig {
+ snippets: vec![Snippet::new(
+ &[],
+ &["ok".into()],
+ &["Ok(${receiver})".into()],
+ "",
+ &[],
+ crate::SnippetScope::Expr,
+ )
+ .unwrap()],
+ ..TEST_CONFIG
+ },
+ "ok",
+ r#"fn main() { &&42.$0 }"#,
+ r#"fn main() { Ok(&&42) }"#,
+ );
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
index 04111ec7e..c142a7305 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
@@ -681,9 +681,13 @@ fn classify_name_ref(
ast::Item::ExternBlock(it) => it.extern_item_list().is_none(),
ast::Item::Fn(it) => it.body().is_none(),
ast::Item::Impl(it) => it.assoc_item_list().is_none(),
- ast::Item::Module(it) => it.item_list().is_none(),
+ ast::Item::Module(it) => {
+ it.item_list().is_none() && it.semicolon_token().is_none()
+ }
ast::Item::Static(it) => it.body().is_none(),
- ast::Item::Struct(it) => it.field_list().is_none(),
+ ast::Item::Struct(it) => {
+ it.field_list().is_none() && it.semicolon_token().is_none()
+ }
ast::Item::Trait(it) => it.assoc_item_list().is_none(),
ast::Item::TypeAlias(it) => it.ty().is_none(),
ast::Item::Union(it) => it.record_field_list().is_none(),
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs
index 5076c6e86..8ed6cb3cf 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs
@@ -245,3 +245,35 @@ impl Test for () {
"#]],
);
}
+
+#[test]
+fn after_unit_struct() {
+ check(
+ r#"struct S; f$0"#,
+ expect![[r#"
+ ma makro!(…) macro_rules! makro
+ md module
+ kw const
+ kw crate::
+ kw enum
+ kw extern
+ kw fn
+ kw impl
+ kw mod
+ kw pub
+ kw pub(crate)
+ kw pub(super)
+ kw self::
+ kw static
+ kw struct
+ kw trait
+ kw type
+ kw union
+ kw unsafe
+ kw use
+ sn macro_rules
+ sn tfn (Test function)
+ sn tmod (Test module)
+ "#]],
+ );
+}