diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index b6a066f4f51..333a3338753 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -430,8 +430,9 @@ pub(crate) fn add_field( Visible::Editable => true, Visible::No => return, }; + let doc_aliases = ctx.doc_aliases(&field); let item = render_field( - RenderContext::new(ctx).private_editable(is_private_editable), + RenderContext::new(ctx).private_editable(is_private_editable).doc_aliases(doc_aliases), dot_access, receiver, field, diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs index f6478d2ceb2..f9bc13f7d2e 100644 --- a/crates/ide-completion/src/context.rs +++ b/crates/ide-completion/src/context.rs @@ -441,6 +441,14 @@ pub(crate) fn is_visible(&self, item: &I) -> Visible self.is_visible_impl(&vis, &attrs, item.krate(self.db)) } + pub(crate) fn doc_aliases(&self, item: &I) -> Vec + where + I: hir::HasAttrs + Copy, + { + let attrs = item.attrs(self.db); + attrs.doc_aliases().collect() + } + /// Check if an item is `#[doc(hidden)]`. pub(crate) fn is_item_hidden(&self, item: &hir::ItemInNs) -> bool { let attrs = item.attrs(self.db); @@ -499,7 +507,7 @@ pub(crate) fn process_all_names(&self, f: &mut dyn FnMut(Name, ScopeDef, Vec bool self.krate != defining_crate && attrs.has_doc_hidden() } - fn doc_aliases(&self, scope_def: ScopeDef) -> Vec { + fn doc_aliases_in_scope(&self, scope_def: ScopeDef) -> Vec { if let Some(attrs) = scope_def.attrs(self.db) { attrs.doc_aliases().collect() } else { diff --git a/crates/ide-completion/src/item.rs b/crates/ide-completion/src/item.rs index c2c4a663c61..ab27b8c0a9f 100644 --- a/crates/ide-completion/src/item.rs +++ b/crates/ide-completion/src/item.rs @@ -4,6 +4,7 @@ use hir::{Documentation, Mutability}; use ide_db::{imports::import_assets::LocatedImport, SnippetCap, SymbolKind}; +use itertools::Itertools; use smallvec::SmallVec; use stdx::{impl_from, never}; use syntax::{SmolStr, TextRange, TextSize}; @@ -353,7 +354,7 @@ pub(crate) fn new( relevance: CompletionRelevance::default(), ref_match: None, imports_to_add: Default::default(), - doc_aliases: None, + doc_aliases: vec![], } } @@ -386,7 +387,7 @@ pub(crate) struct Builder { source_range: TextRange, imports_to_add: SmallVec<[LocatedImport; 1]>, trait_name: Option, - doc_aliases: Option, + doc_aliases: Vec, label: SmolStr, insert_text: Option, is_snippet: bool, @@ -418,7 +419,8 @@ pub(crate) fn build(self) -> CompletionItem { let mut lookup = self.lookup.unwrap_or_else(|| label.clone()); let insert_text = self.insert_text.unwrap_or_else(|| label.to_string()); - if let Some(doc_aliases) = self.doc_aliases { + if !self.doc_aliases.is_empty() { + let doc_aliases = self.doc_aliases.into_iter().join(", "); label = SmolStr::from(format!("{label} (alias {doc_aliases})")); lookup = SmolStr::from(format!("{lookup} {doc_aliases}")); } @@ -464,8 +466,8 @@ pub(crate) fn trait_name(&mut self, trait_name: SmolStr) -> &mut Builder { self.trait_name = Some(trait_name); self } - pub(crate) fn doc_aliases(&mut self, doc_aliases: SmolStr) -> &mut Builder { - self.doc_aliases = Some(doc_aliases); + pub(crate) fn doc_aliases(&mut self, doc_aliases: Vec) -> &mut Builder { + self.doc_aliases = doc_aliases; self } pub(crate) fn insert_text(&mut self, insert_text: impl Into) -> &mut Builder { diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index 514a6847266..62a357e085a 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -152,6 +152,7 @@ pub(crate) fn render_field( } } } + item.doc_aliases(ctx.doc_aliases); item.build() } @@ -361,11 +362,7 @@ fn render_resolution_simple_( item.add_import(import_to_add); } - let doc_aliases = ctx.doc_aliases; - if !doc_aliases.is_empty() { - let doc_aliases = doc_aliases.into_iter().join(", ").into(); - item.doc_aliases(doc_aliases); - } + item.doc_aliases(ctx.doc_aliases); item } diff --git a/crates/ide-completion/src/tests/special.rs b/crates/ide-completion/src/tests/special.rs index 1749e8e70f8..5f53e5b6a9b 100644 --- a/crates/ide-completion/src/tests/special.rs +++ b/crates/ide-completion/src/tests/special.rs @@ -1086,3 +1086,22 @@ fn here_we_go() fn() "#]], ); } + +#[test] +fn completes_field_name_via_doc_alias_in_fn_body() { + check( + r#" +struct Foo { + #[doc(alias = "qux")] + bar: u8 +}; + +fn here_we_go() { + let foo = Foo { q$0 } +} +"#, + expect![[r#" + fd bar (alias qux) u8 + "#]], + ); +}