]> git.lizzy.rs Git - rust.git/blobdiff - crates/ide-completion/src/render/variant.rs
fix: format literal lookup
[rust.git] / crates / ide-completion / src / render / variant.rs
index 39a37dc9f8ec2bfc559a3a3e868ba34f597607f4..24e6abdc9ad60918472e7508cad3b8c4f3cc5eef 100644 (file)
@@ -1,7 +1,7 @@
 //! Code common to structs, unions, and enum variants.
 
 use crate::context::CompletionContext;
-use hir::{db::HirDatabase, HasAttrs, HasVisibility, HirDisplay, StructKind};
+use hir::{db::HirDatabase, HasAttrs, HasCrate, HasVisibility, HirDisplay, StructKind};
 use ide_db::SnippetCap;
 use itertools::Itertools;
 use syntax::SmolStr;
@@ -68,9 +68,9 @@ pub(crate) fn render_tuple_lit(
 /// fields, plus a boolean for whether the list is comprehensive (contains no
 /// private fields and its item is not marked `#[non_exhaustive]`).
 pub(crate) fn visible_fields(
-    ctx: &CompletionContext,
+    ctx: &CompletionContext<'_>,
     fields: &[hir::Field],
-    item: impl HasAttrs,
+    item: impl HasAttrs + HasCrate + Copy,
 ) -> Option<(Vec<hir::Field>, bool)> {
     let module = ctx.module;
     let n_fields = fields.len();
@@ -79,9 +79,10 @@ pub(crate) fn visible_fields(
         .filter(|field| field.is_visible_from(ctx.db, module))
         .copied()
         .collect::<Vec<_>>();
-
-    let fields_omitted =
-        n_fields - fields.len() > 0 || item.attrs(ctx.db).by_key("non_exhaustive").exists();
+    let has_invisible_field = n_fields - fields.len() > 0;
+    let is_foreign_non_exhaustive = item.attrs(ctx.db).by_key("non_exhaustive").exists()
+        && item.krate(ctx.db) != module.krate();
+    let fields_omitted = has_invisible_field || is_foreign_non_exhaustive;
     Some((fields, fields_omitted))
 }
 
@@ -93,3 +94,12 @@ pub(crate) fn format_literal_label(name: &str, kind: StructKind) -> SmolStr {
         StructKind::Unit => name.into(),
     }
 }
+
+/// Format a struct, etc. literal option for lookup used in completions filtering.
+pub(crate) fn format_literal_lookup(name: &str, kind: StructKind) -> SmolStr {
+    match kind {
+        StructKind::Tuple => SmolStr::from_iter([name, "()"]),
+        StructKind::Record => SmolStr::from_iter([name, "{}"]),
+        StructKind::Unit => name.into(),
+    }
+}