Unnamed repository; edit this file 'description' to name the repository.
-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.rs22
3 files changed, 56 insertions, 5 deletions
diff --git a/crates/ide_completion/src/completions.rs b/crates/ide_completion/src/completions.rs
index 3b88085d2d..8474ebec0d 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 f0c81f66bc..d50f889ee4 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 a70015dcaf..bfbcc263b1 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,27 @@ fn build_completion(
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,
};