]> git.lizzy.rs Git - rust.git/blobdiff - crates/ide_completion/src/render/struct_literal.rs
Merge #11393
[rust.git] / crates / ide_completion / src / render / struct_literal.rs
index a6571eb02234ab1029d92a4096083ae0124e8bb4..6be7b9d43bc87dc1872e13551fb29520a5f2a251 100644 (file)
@@ -3,12 +3,14 @@
 use hir::{db::HirDatabase, HasAttrs, HasVisibility, Name, StructKind};
 use ide_db::helpers::SnippetCap;
 use itertools::Itertools;
+use syntax::SmolStr;
 
-use crate::{item::CompletionKind, render::RenderContext, CompletionItem, CompletionItemKind};
+use crate::{render::RenderContext, CompletionItem, CompletionItemKind};
 
 pub(crate) fn render_struct_literal(
     ctx: RenderContext<'_>,
     strukt: hir::Struct,
+    path: Option<hir::ModPath>,
     local_name: Option<Name>,
 ) -> Option<CompletionItem> {
     let _p = profile::span("render_struct_literal");
@@ -21,48 +23,58 @@ pub(crate) fn render_struct_literal(
         return None;
     }
 
-    let name = local_name.unwrap_or_else(|| strukt.name(ctx.db())).to_string();
-    let literal = render_literal(&ctx, &name, strukt.kind(ctx.db()), &visible_fields)?;
+    let name = local_name.unwrap_or_else(|| strukt.name(ctx.db())).to_smol_str();
+
+    let literal = render_literal(&ctx, path, &name, strukt.kind(ctx.db()), &visible_fields)?;
 
     Some(build_completion(ctx, name, literal, strukt))
 }
 
 fn build_completion(
     ctx: RenderContext<'_>,
-    name: String,
+    name: SmolStr,
     literal: String,
     def: impl HasAttrs + Copy,
 ) -> CompletionItem {
-    let mut item = CompletionItem::new(CompletionKind::Snippet, ctx.source_range(), name + " {…}");
-    item.kind(CompletionItemKind::Snippet)
-        .set_documentation(ctx.docs(def))
-        .set_deprecated(ctx.is_deprecated(def))
-        .detail(&literal);
-    if let Some(snippet_cap) = ctx.snippet_cap() {
-        item.insert_snippet(snippet_cap, literal);
-    } else {
-        item.insert_text(literal);
+    let mut item = CompletionItem::new(
+        CompletionItemKind::Snippet,
+        ctx.source_range(),
+        SmolStr::from_iter([&name, " {…}"]),
+    );
+    item.set_documentation(ctx.docs(def)).set_deprecated(ctx.is_deprecated(def)).detail(&literal);
+    match ctx.snippet_cap() {
+        Some(snippet_cap) => item.insert_snippet(snippet_cap, literal),
+        None => item.insert_text(literal),
     };
     item.build()
 }
 
 fn render_literal(
     ctx: &RenderContext<'_>,
+    path: Option<hir::ModPath>,
     name: &str,
     kind: StructKind,
     fields: &[hir::Field],
 ) -> Option<String> {
+    let path_string;
+
+    let qualified_name = if let Some(path) = path {
+        path_string = path.to_string();
+        &path_string
+    } else {
+        name
+    };
+
     let mut literal = match kind {
-        StructKind::Tuple if ctx.snippet_cap().is_some() => render_tuple_as_literal(fields, name),
-        StructKind::Record => render_record_as_literal(ctx.db(), ctx.snippet_cap(), fields, name),
+        StructKind::Tuple if ctx.snippet_cap().is_some() => {
+            render_tuple_as_literal(fields, qualified_name)
+        }
+        StructKind::Record => {
+            render_record_as_literal(ctx.db(), ctx.snippet_cap(), fields, qualified_name)
+        }
         _ => return None,
     };
 
-    if ctx.completion.is_param {
-        literal.push(':');
-        literal.push(' ');
-        literal.push_str(name);
-    }
     if ctx.snippet_cap().is_some() {
         literal.push_str("$0");
     }
@@ -107,7 +119,7 @@ fn visible_fields(
     fields: &[hir::Field],
     item: impl HasAttrs,
 ) -> Option<(Vec<hir::Field>, bool)> {
-    let module = ctx.completion.scope.module()?;
+    let module = ctx.completion.module?;
     let n_fields = fields.len();
     let fields = fields
         .iter()