about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/ide/src/inlay_hints.rs27
-rw-r--r--crates/ide_completion/src/context.rs3
-rw-r--r--crates/ide_completion/src/render.rs2
-rw-r--r--crates/ide_completion/src/render/enum_variant.rs7
-rw-r--r--crates/ide_completion/src/render/function.rs2
-rw-r--r--crates/ide_completion/src/render/struct_literal.rs11
-rw-r--r--crates/ide_completion/src/render/union_literal.rs5
-rw-r--r--crates/ide_completion/src/render/variant.rs (renamed from crates/ide_completion/src/render/compound.rs)10
-rw-r--r--crates/ide_completion/src/tests/pattern.rs68
-rw-r--r--crates/ide_completion/src/tests/record.rs2
10 files changed, 101 insertions, 36 deletions
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 322a9b820a6..428b8d1109f 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -69,24 +69,17 @@ pub(crate) fn inlay_hints(
 
     let mut hints = Vec::new();
 
-    if let Some(range_limit) = range_limit {
-        let range_limit = range_limit.range;
-        match file.covering_element(range_limit) {
+    let get_hints = |node| get_hints(&mut hints, &sema, config, node);
+    match range_limit {
+        Some(FileRange { range, .. }) => match file.covering_element(range) {
             NodeOrToken::Token(_) => return hints,
-            NodeOrToken::Node(n) => {
-                for node in n
-                    .descendants()
-                    .filter(|descendant| range_limit.contains_range(descendant.text_range()))
-                {
-                    get_hints(&mut hints, &sema, config, node);
-                }
-            }
-        }
-    } else {
-        for node in file.descendants() {
-            get_hints(&mut hints, &sema, config, node);
-        }
-    }
+            NodeOrToken::Node(n) => n
+                .descendants()
+                .filter(|descendant| range.contains_range(descendant.text_range()))
+                .for_each(get_hints),
+        },
+        None => file.descendants().for_each(get_hints),
+    };
 
     hints
 }
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index 1ad233494a9..ed59eb6bd3e 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -58,7 +58,7 @@ pub(super) enum PathKind {
 
 #[derive(Debug)]
 pub(crate) struct PathCompletionCtx {
-    /// If this is a call with () already there
+    /// If this is a call with () already there (or {} in case of record patterns)
     pub(super) has_call_parens: bool,
     /// Whether this path stars with a `::`.
     pub(super) is_absolute_path: bool,
@@ -890,6 +890,7 @@ impl<'a> CompletionContext<'a> {
                         Some(PathKind::Pat)
                     },
                     ast::RecordPat(it) => {
+                        path_ctx.has_call_parens = true;
                         pat_ctx = Some(pattern_context_for(original_file, it.into()));
                         Some(PathKind::Pat)
                     },
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index 0ed346c55e2..d6fa86b55da 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -8,7 +8,7 @@ pub(crate) mod const_;
 pub(crate) mod pattern;
 pub(crate) mod type_alias;
 pub(crate) mod struct_literal;
-pub(crate) mod compound;
+pub(crate) mod variant;
 pub(crate) mod union_literal;
 
 use hir::{AsAssocItem, HasAttrs, HirDisplay, ScopeDef};
diff --git a/crates/ide_completion/src/render/enum_variant.rs b/crates/ide_completion/src/render/enum_variant.rs
index 5b485005d3f..9e27a84e2f7 100644
--- a/crates/ide_completion/src/render/enum_variant.rs
+++ b/crates/ide_completion/src/render/enum_variant.rs
@@ -7,8 +7,9 @@ use syntax::SmolStr;
 use crate::{
     item::{CompletionItem, ImportEdit},
     render::{
-        compound::{format_literal_label, render_record, render_tuple, RenderedCompound},
-        compute_ref_match, compute_type_match, RenderContext,
+        compute_ref_match, compute_type_match,
+        variant::{format_literal_label, render_record, render_tuple, RenderedLiteral},
+        RenderContext,
     },
     CompletionRelevance,
 };
@@ -56,7 +57,7 @@ fn render(
             render_record(db, ctx.snippet_cap(), &variant.fields(db), Some(&qualified_name))
         }
         StructKind::Unit => {
-            RenderedCompound { literal: qualified_name.clone(), detail: qualified_name.clone() }
+            RenderedLiteral { literal: qualified_name.clone(), detail: qualified_name.clone() }
         }
     };
 
diff --git a/crates/ide_completion/src/render/function.rs b/crates/ide_completion/src/render/function.rs
index 2b9f82fc54e..6a46de4229a 100644
--- a/crates/ide_completion/src/render/function.rs
+++ b/crates/ide_completion/src/render/function.rs
@@ -192,7 +192,7 @@ fn should_add_parens(ctx: &CompletionContext) -> bool {
         Some(PathCompletionCtx { kind: Some(PathKind::Expr), has_call_parens: true, .. }) => {
             return false
         }
-        Some(PathCompletionCtx { kind: Some(PathKind::Use), .. }) => {
+        Some(PathCompletionCtx { kind: Some(PathKind::Use | PathKind::Type), .. }) => {
             cov_mark::hit!(no_parens_in_use_item);
             return false;
         }
diff --git a/crates/ide_completion/src/render/struct_literal.rs b/crates/ide_completion/src/render/struct_literal.rs
index a686be66913..b4fa26add1f 100644
--- a/crates/ide_completion/src/render/struct_literal.rs
+++ b/crates/ide_completion/src/render/struct_literal.rs
@@ -1,11 +1,12 @@
 //! Renderer for `struct` literal.
 
 use hir::{HasAttrs, Name, StructKind};
+use ide_db::SymbolKind;
 use syntax::SmolStr;
 
 use crate::{
-    render::compound::{
-        format_literal_label, render_record, render_tuple, visible_fields, RenderedCompound,
+    render::variant::{
+        format_literal_label, render_record, render_tuple, visible_fields, RenderedLiteral,
     },
     render::RenderContext,
     CompletionItem, CompletionItemKind,
@@ -37,12 +38,12 @@ pub(crate) fn render_struct_literal(
 fn build_completion(
     ctx: &RenderContext<'_>,
     name: SmolStr,
-    rendered: RenderedCompound,
+    rendered: RenderedLiteral,
     kind: StructKind,
     def: impl HasAttrs + Copy,
 ) -> CompletionItem {
     let mut item = CompletionItem::new(
-        CompletionItemKind::Snippet,
+        CompletionItemKind::SymbolKind(SymbolKind::Struct),
         ctx.source_range(),
         format_literal_label(&name, kind),
     );
@@ -64,7 +65,7 @@ fn render_literal(
     name: &str,
     kind: StructKind,
     fields: &[hir::Field],
-) -> Option<RenderedCompound> {
+) -> Option<RenderedLiteral> {
     let path_string;
 
     let qualified_name = if let Some(path) = path {
diff --git a/crates/ide_completion/src/render/union_literal.rs b/crates/ide_completion/src/render/union_literal.rs
index 80499e102b4..209f0069821 100644
--- a/crates/ide_completion/src/render/union_literal.rs
+++ b/crates/ide_completion/src/render/union_literal.rs
@@ -1,11 +1,12 @@
 //! Renderer for `union` literals.
 
 use hir::{HirDisplay, Name, StructKind};
+use ide_db::SymbolKind;
 use itertools::Itertools;
 
 use crate::{
     render::{
-        compound::{format_literal_label, visible_fields},
+        variant::{format_literal_label, visible_fields},
         RenderContext,
     },
     CompletionItem, CompletionItemKind,
@@ -25,7 +26,7 @@ pub(crate) fn render_union_literal(
     };
 
     let mut item = CompletionItem::new(
-        CompletionItemKind::Snippet,
+        CompletionItemKind::SymbolKind(SymbolKind::Union),
         ctx.source_range(),
         format_literal_label(&name, StructKind::Record),
     );
diff --git a/crates/ide_completion/src/render/compound.rs b/crates/ide_completion/src/render/variant.rs
index c7f3bd1f79a..e6a92f387ea 100644
--- a/crates/ide_completion/src/render/compound.rs
+++ b/crates/ide_completion/src/render/variant.rs
@@ -9,7 +9,7 @@ use syntax::SmolStr;
 /// A rendered struct, union, or enum variant, split into fields for actual
 /// auto-completion (`literal`, using `field: ()`) and display in the
 /// completions menu (`detail`, using `field: type`).
-pub(crate) struct RenderedCompound {
+pub(crate) struct RenderedLiteral {
     pub(crate) literal: String,
     pub(crate) detail: String,
 }
@@ -21,7 +21,7 @@ pub(crate) fn render_record(
     snippet_cap: Option<SnippetCap>,
     fields: &[hir::Field],
     name: Option<&str>,
-) -> RenderedCompound {
+) -> RenderedLiteral {
     let completions = fields.iter().enumerate().format_with(", ", |(idx, field), f| {
         if snippet_cap.is_some() {
             f(&format_args!("{}: ${{{}:()}}", field.name(db), idx + 1))
@@ -34,7 +34,7 @@ pub(crate) fn render_record(
         f(&format_args!("{}: {}", field.name(db), field.ty(db).display(db)))
     });
 
-    RenderedCompound {
+    RenderedLiteral {
         literal: format!("{} {{ {} }}", name.unwrap_or(""), completions),
         detail: format!("{} {{ {} }}", name.unwrap_or(""), types),
     }
@@ -47,7 +47,7 @@ pub(crate) fn render_tuple(
     snippet_cap: Option<SnippetCap>,
     fields: &[hir::Field],
     name: Option<&str>,
-) -> RenderedCompound {
+) -> RenderedLiteral {
     let completions = fields.iter().enumerate().format_with(", ", |(idx, _), f| {
         if snippet_cap.is_some() {
             f(&format_args!("${{{}:()}}", idx + 1))
@@ -58,7 +58,7 @@ pub(crate) fn render_tuple(
 
     let types = fields.iter().format_with(", ", |field, f| f(&field.ty(db).display(db)));
 
-    RenderedCompound {
+    RenderedLiteral {
         literal: format!("{}({})", name.unwrap_or(""), completions),
         detail: format!("{}({})", name.unwrap_or(""), types),
     }
diff --git a/crates/ide_completion/src/tests/pattern.rs b/crates/ide_completion/src/tests/pattern.rs
index 891c1346dfc..28b6ba6a374 100644
--- a/crates/ide_completion/src/tests/pattern.rs
+++ b/crates/ide_completion/src/tests/pattern.rs
@@ -378,3 +378,71 @@ fn foo() {
         "#]],
     )
 }
+
+#[test]
+fn completes_no_delims_if_existing() {
+    check_empty(
+        r#"
+struct Bar(u32);
+fn foo() {
+    match Bar(0) {
+        B$0(b) => {}
+    }
+}
+"#,
+        expect![[r#"
+            kw self::
+            kw super::
+            kw crate::
+        "#]],
+    );
+    check_empty(
+        r#"
+struct Foo { bar: u32 }
+fn foo() {
+    match Foo { bar: 0 } {
+        F$0 { bar } => {}
+    }
+}
+"#,
+        expect![[r#"
+            kw return
+            kw self
+            kw super
+            kw crate
+            st Foo
+            fn foo()  fn()
+            bt u32
+        "#]],
+    );
+    check_empty(
+        r#"
+enum Enum {
+    TupleVariant(u32)
+}
+fn foo() {
+    match Enum::TupleVariant(0) {
+        Enum::T$0(b) => {}
+    }
+}
+"#,
+        expect![[r#"
+            ev TupleVariant(…) TupleVariant(u32)
+        "#]],
+    );
+    check_empty(
+        r#"
+enum Enum {
+    RecordVariant { field: u32 }
+}
+fn foo() {
+    match (Enum::RecordVariant { field: 0 }) {
+        Enum::RecordV$0 { field } => {}
+    }
+}
+"#,
+        expect![[r#"
+            ev RecordVariant {…} RecordVariant { field: u32 }
+        "#]],
+    );
+}
diff --git a/crates/ide_completion/src/tests/record.rs b/crates/ide_completion/src/tests/record.rs
index 5e9367960f7..0322ecbe39f 100644
--- a/crates/ide_completion/src/tests/record.rs
+++ b/crates/ide_completion/src/tests/record.rs
@@ -166,7 +166,7 @@ fn main() {
             kw true
             kw false
             kw return
-            sn Foo {…}              Foo { foo1: u32, foo2: u32 }
+            st Foo {…}              Foo { foo1: u32, foo2: u32 }
             fd ..Default::default()
             fd foo1                 u32
             fd foo2                 u32