//! 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;
/// 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();
.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))
}
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(),
+ }
+}