about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-06-30 11:10:59 +0000
committerbors <bors@rust-lang.org>2024-06-30 11:10:59 +0000
commitacdfab645ffb48ce1735da9a43af3ed182dcaa0b (patch)
tree2def6ef3856ab379880406ae307f258dd77a75b8 /src
parentfde55648116f75eb44340047d48a191d0660a403 (diff)
parent71bc01370c3898620d69436e46a2c5f8ae28a2f9 (diff)
downloadrust-acdfab645ffb48ce1735da9a43af3ed182dcaa0b.tar.gz
rust-acdfab645ffb48ce1735da9a43af3ed182dcaa0b.zip
Auto merge of #17513 - roife:fix-issue-17500, r=Veykril
fix: completions after async kw

fix #17500

### Changes

1. fix completions after async kw
2. fix completions for `async` kw in trait
Diffstat (limited to 'src')
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list.rs19
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs13
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs19
5 files changed, 48 insertions, 8 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list.rs
index 02298b1e9b0..18833774083 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list.rs
@@ -82,17 +82,30 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
     let no_vis_qualifiers = ctx.qualifier_ctx.vis_node.is_none();
     let in_block = kind.is_none();
 
+    let missing_qualifiers = [
+        ctx.qualifier_ctx.unsafe_tok.is_none().then_some(("unsafe", "unsafe $0")),
+        ctx.qualifier_ctx.async_tok.is_none().then_some(("async", "async $0")),
+    ];
+
     if !in_trait_impl {
-        if ctx.qualifier_ctx.unsafe_tok.is_some() {
+        // handle qualifier tokens
+        if missing_qualifiers.iter().any(Option::is_none) {
+            // only complete missing qualifiers
+            missing_qualifiers.iter().filter_map(|x| *x).for_each(|(kw, snippet)| {
+                add_keyword(kw, snippet);
+            });
+
             if in_item_list || in_assoc_non_trait_impl {
                 add_keyword("fn", "fn $1($2) {\n    $0\n}");
             }
-            if in_item_list {
+
+            if ctx.qualifier_ctx.unsafe_tok.is_some() && in_item_list {
                 add_keyword("trait", "trait $1 {\n    $0\n}");
                 if no_vis_qualifiers {
                     add_keyword("impl", "impl $1 {\n    $0\n}");
                 }
             }
+
             return;
         }
 
@@ -100,7 +113,6 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
             add_keyword("enum", "enum $1 {\n    $0\n}");
             add_keyword("mod", "mod $0");
             add_keyword("static", "static $0");
-            add_keyword("async", "async $0");
             add_keyword("struct", "struct $0");
             add_keyword("trait", "trait $1 {\n    $0\n}");
             add_keyword("union", "union $1 {\n    $0\n}");
@@ -129,6 +141,7 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
             add_keyword("fn", "fn $1($2) {\n    $0\n}");
             add_keyword("unsafe", "unsafe $0");
             add_keyword("const", "const $0");
+            add_keyword("async", "async $0");
         }
     }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs
index d79b5398828..3f50cd55cb3 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs
@@ -57,6 +57,7 @@ mod tests {
         check(
             r"fn my_fn() { unsafe $0 }",
             expect![[r#"
+                kw async
                 kw fn
                 kw impl
                 kw trait
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
index 992ca18bb06..5782a4423a6 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
@@ -46,13 +46,15 @@ pub(crate) enum Visible {
 /// Existing qualifiers for the thing we are currently completing.
 #[derive(Debug, Default)]
 pub(crate) struct QualifierCtx {
+    // TODO: Add try_tok and default_tok
+    pub(crate) async_tok: Option<SyntaxToken>,
     pub(crate) unsafe_tok: Option<SyntaxToken>,
     pub(crate) vis_node: Option<ast::Visibility>,
 }
 
 impl QualifierCtx {
     pub(crate) fn none(&self) -> bool {
-        self.unsafe_tok.is_none() && self.vis_node.is_none()
+        self.async_tok.is_none() && self.unsafe_tok.is_none() && self.vis_node.is_none()
     }
 }
 
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 743aa005708..80dcfd2f524 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
@@ -1287,10 +1287,15 @@ fn classify_name_ref(
                 syntax::algo::non_trivia_sibling(top.clone().into(), syntax::Direction::Prev)
             {
                 if error_node.kind() == SyntaxKind::ERROR {
-                    qualifier_ctx.unsafe_tok = error_node
-                        .children_with_tokens()
-                        .filter_map(NodeOrToken::into_token)
-                        .find(|it| it.kind() == T![unsafe]);
+                    for token in
+                        error_node.children_with_tokens().filter_map(NodeOrToken::into_token)
+                    {
+                        match token.kind() {
+                            SyntaxKind::UNSAFE_KW => qualifier_ctx.unsafe_tok = Some(token),
+                            SyntaxKind::ASYNC_KW => qualifier_ctx.async_tok = Some(token),
+                            _ => {}
+                        }
+                    }
                     qualifier_ctx.vis_node = error_node.children().find_map(ast::Visibility::cast);
                 }
             }
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 c37900478e1..f138938b02b 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
@@ -123,6 +123,7 @@ fn after_unsafe_token() {
     check(
         r#"unsafe $0"#,
         expect![[r#"
+            kw async
             kw fn
             kw impl
             kw trait
@@ -131,6 +132,17 @@ fn after_unsafe_token() {
 }
 
 #[test]
+fn after_async_token() {
+    check(
+        r#"async $0"#,
+        expect![[r#"
+            kw fn
+            kw unsafe
+        "#]],
+    );
+}
+
+#[test]
 fn after_visibility() {
     check(
         r#"pub $0"#,
@@ -157,6 +169,7 @@ fn after_visibility_unsafe() {
     check(
         r#"pub unsafe $0"#,
         expect![[r#"
+            kw async
             kw fn
             kw trait
         "#]],
@@ -170,6 +183,7 @@ fn in_impl_assoc_item_list() {
         expect![[r#"
             ma makro!(…)  macro_rules! makro
             md module
+            kw async
             kw const
             kw crate::
             kw fn
@@ -189,6 +203,7 @@ fn in_impl_assoc_item_list_after_attr() {
         expect![[r#"
             ma makro!(…)  macro_rules! makro
             md module
+            kw async
             kw const
             kw crate::
             kw fn
@@ -208,6 +223,7 @@ fn in_trait_assoc_item_list() {
         expect![[r#"
             ma makro!(…) macro_rules! makro
             md module
+            kw async
             kw const
             kw crate::
             kw fn
@@ -225,6 +241,7 @@ fn in_trait_assoc_fn_missing_body() {
         expect![[r#"
             ma makro!(…) macro_rules! makro
             md module
+            kw async
             kw const
             kw crate::
             kw fn
@@ -242,6 +259,7 @@ fn in_trait_assoc_const_missing_body() {
         expect![[r#"
             ma makro!(…) macro_rules! makro
             md module
+            kw async
             kw const
             kw crate::
             kw fn
@@ -259,6 +277,7 @@ fn in_trait_assoc_type_aliases_missing_ty() {
         expect![[r#"
             ma makro!(…) macro_rules! makro
             md module
+            kw async
             kw const
             kw crate::
             kw fn