about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndrew Leverette <andrewleverette@gmail.com>2021-11-23 10:57:29 -0600
committerAndrew Leverette <andrewleverette@gmail.com>2021-11-23 10:57:29 -0600
commitce7a141110e9c3daf984596d7fcbcb489e5677c4 (patch)
tree5676e2c7f98d53a1fe471c97f16a225f37e2a64d
parent054873ce15ea7ba0e21b6508abe97fd0cb54ec8c (diff)
downloadrust-ce7a141110e9c3daf984596d7fcbcb489e5677c4.tar.gz
rust-ce7a141110e9c3daf984596d7fcbcb489e5677c4.zip
Add support for qualified struct names
-rw-r--r--crates/ide_completion/src/completions.rs3
-rw-r--r--crates/ide_completion/src/completions/record.rs36
-rw-r--r--crates/ide_completion/src/render/struct_literal.rs15
3 files changed, 49 insertions, 5 deletions
diff --git a/crates/ide_completion/src/completions.rs b/crates/ide_completion/src/completions.rs
index 3b88085d2de..8474ebec0d9 100644
--- a/crates/ide_completion/src/completions.rs
+++ b/crates/ide_completion/src/completions.rs
@@ -191,9 +191,10 @@ impl Completions {
         &mut self,
         ctx: &CompletionContext,
         strukt: hir::Struct,
+        path: Option<hir::ModPath>,
         local_name: Option<hir::Name>,
     ) {
-        let item = render_struct_literal(RenderContext::new(ctx), strukt, local_name);
+        let item = render_struct_literal(RenderContext::new(ctx), strukt, path, local_name);
         self.add_opt(item);
     }
 
diff --git a/crates/ide_completion/src/completions/record.rs b/crates/ide_completion/src/completions/record.rs
index f0c81f66bc8..d50f889ee47 100644
--- a/crates/ide_completion/src/completions/record.rs
+++ b/crates/ide_completion/src/completions/record.rs
@@ -59,7 +59,12 @@ pub(crate) fn complete_record_literal(
     }
 
     if let hir::Adt::Struct(strukt) = ctx.expected_type.as_ref()?.as_adt()? {
-        acc.add_struct_literal(ctx, strukt, None);
+        let module =
+            if let Some(module) = ctx.scope.module() { module } else { strukt.module(ctx.db) };
+
+        let path = module.find_use_path(ctx.db, hir::ModuleDef::from(strukt));
+
+        acc.add_struct_literal(ctx, strukt, path, None);
     }
 
     Some(())
@@ -95,6 +100,35 @@ fn baz() {
     }
 
     #[test]
+    fn literal_struct_completion_from_sub_modules() {
+        check_edit(
+            "Struct {…}",
+            r#"
+mod submod {
+    pub struct Struct {
+        pub a: u64,
+    }
+}
+
+fn f() -> submod::Struct {
+    Stru$0
+}
+            "#,
+            r#"
+mod submod {
+    pub struct Struct {
+        pub a: u64,
+    }
+}
+
+fn f() -> submod::Struct {
+    submod::Struct { a: ${1:()} }$0
+}
+            "#,
+        )
+    }
+
+    #[test]
     fn literal_struct_complexion_module() {
         check_edit(
             "FooDesc {…}",
diff --git a/crates/ide_completion/src/render/struct_literal.rs b/crates/ide_completion/src/render/struct_literal.rs
index a70015dcaf6..581b4a84ceb 100644
--- a/crates/ide_completion/src/render/struct_literal.rs
+++ b/crates/ide_completion/src/render/struct_literal.rs
@@ -10,6 +10,7 @@ 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");
@@ -23,7 +24,8 @@ pub(crate) fn render_struct_literal(
     }
 
     let name = local_name.unwrap_or_else(|| strukt.name(ctx.db())).to_smol_str();
-    let literal = render_literal(&ctx, &name, strukt.kind(ctx.db()), &visible_fields)?;
+
+    let literal = render_literal(&ctx, path, &name, strukt.kind(ctx.db()), &visible_fields)?;
 
     Some(build_completion(ctx, name, literal, strukt))
 }
@@ -49,13 +51,20 @@ fn build_completion(
 
 fn render_literal(
     ctx: &RenderContext<'_>,
+    path: Option<hir::ModPath>,
     name: &str,
     kind: StructKind,
     fields: &[hir::Field],
 ) -> Option<String> {
+    let qualified_name = if let Some(path) = path { path.to_string() } else { name.to_string() };
+
     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,
     };