Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/import_map.rs')
-rw-r--r--crates/hir-def/src/import_map.rs42
1 files changed, 32 insertions, 10 deletions
diff --git a/crates/hir-def/src/import_map.rs b/crates/hir-def/src/import_map.rs
index 4b2e5041a1..6038caaf8f 100644
--- a/crates/hir-def/src/import_map.rs
+++ b/crates/hir-def/src/import_map.rs
@@ -11,6 +11,7 @@ use itertools::Itertools;
use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
use triomphe::Arc;
+use crate::item_scope::ImportOrExternCrate;
use crate::{
db::DefDatabase, item_scope::ItemInNs, nameres::DefMap, visibility::Visibility, AssocItemId,
ModuleDefId, ModuleId, TraitId,
@@ -29,6 +30,8 @@ pub struct ImportInfo {
pub container: ModuleId,
/// Whether the import is a trait associated item or not.
pub is_trait_assoc_item: bool,
+ /// Whether this item is annotated with `#[doc(hidden)]`.
+ pub is_doc_hidden: bool,
}
/// A map from publicly exported items to its name.
@@ -109,23 +112,41 @@ fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> FxIndexMap<ItemIn
});
for (name, per_ns) in visible_items {
- for item in per_ns.iter_items() {
+ for (item, import) in per_ns.iter_items() {
+ // FIXME: Not yet used, but will be once we handle doc(hidden) import sources
+ let attr_id = if let Some(import) = import {
+ match import {
+ ImportOrExternCrate::ExternCrate(id) => Some(id.into()),
+ ImportOrExternCrate::Import(id) => Some(id.import.into()),
+ }
+ } else {
+ match item {
+ ItemInNs::Types(id) | ItemInNs::Values(id) => id.try_into().ok(),
+ ItemInNs::Macros(id) => Some(id.into()),
+ }
+ };
+ let is_doc_hidden =
+ attr_id.map_or(false, |attr_id| db.attrs(attr_id).has_doc_hidden());
+
let import_info = ImportInfo {
name: name.clone(),
container: module,
is_trait_assoc_item: false,
+ is_doc_hidden,
};
match depth_map.entry(item) {
- Entry::Vacant(entry) => {
- entry.insert(depth);
- }
+ Entry::Vacant(entry) => _ = entry.insert((depth, is_doc_hidden)),
Entry::Occupied(mut entry) => {
- if depth < *entry.get() {
- entry.insert(depth);
- } else {
+ let &(occ_depth, occ_is_doc_hidden) = entry.get();
+ // Prefer the one that is not doc(hidden),
+ // Otherwise, if both have the same doc(hidden)-ness and the new path is shorter, prefer that one.
+ let overwrite_entry = occ_is_doc_hidden && !is_doc_hidden
+ || occ_is_doc_hidden == is_doc_hidden && depth < occ_depth;
+ if !overwrite_entry {
continue;
}
+ entry.insert((depth, is_doc_hidden));
}
}
@@ -162,10 +183,10 @@ fn collect_trait_assoc_items(
trait_import_info: &ImportInfo,
) {
let _p = profile::span("collect_trait_assoc_items");
- for (assoc_item_name, item) in &db.trait_data(tr).items {
+ for &(ref assoc_item_name, item) in &db.trait_data(tr).items {
let module_def_id = match item {
- AssocItemId::FunctionId(f) => ModuleDefId::from(*f),
- AssocItemId::ConstId(c) => ModuleDefId::from(*c),
+ AssocItemId::FunctionId(f) => ModuleDefId::from(f),
+ AssocItemId::ConstId(c) => ModuleDefId::from(c),
// cannot use associated type aliases directly: need a `<Struct as Trait>::TypeAlias`
// qualifier, ergo no need to store it for imports in import_map
AssocItemId::TypeAliasId(_) => {
@@ -183,6 +204,7 @@ fn collect_trait_assoc_items(
container: trait_import_info.container,
name: assoc_item_name.clone(),
is_trait_assoc_item: true,
+ is_doc_hidden: db.attrs(item.into()).has_doc_hidden(),
};
map.insert(assoc_item, assoc_item_info);
}