Separate out some IndexItem fields into a new struct and DRY

This commit is contained in:
Yotam Ofek
2025-11-29 14:56:07 +02:00
parent 3142beae24
commit ab1500b8ab
3 changed files with 64 additions and 57 deletions
+6 -17
View File
@@ -15,9 +15,7 @@
use crate::fold::DocFolder;
use crate::formats::Impl;
use crate::formats::item_type::ItemType;
use crate::html::markdown::short_markdown_summary;
use crate::html::render::IndexItem;
use crate::html::render::search_index::get_function_type_for_search;
use crate::html::render::{IndexItem, IndexItemInfo};
use crate::visit_lib::RustdocEffectiveVisibilities;
/// This cache is used to store information about the [`clean::Crate`] being
@@ -576,7 +574,6 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It
debug_assert!(!item.is_stripped());
let desc = short_markdown_summary(&item.doc_value(), &item.link_names(cache));
// For searching purposes, a re-export is a duplicate if:
//
// - It's either an inline, or a true re-export
@@ -587,32 +584,24 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It
_ => item_def_id,
};
let (impl_id, trait_parent) = cache.parent_stack_last_impl_and_trait_id();
let search_type = get_function_type_for_search(
item,
let info = IndexItemInfo::new(
tcx,
clean_impl_generics(cache.parent_stack.last()).as_ref(),
parent_did,
cache,
item,
parent_did,
clean_impl_generics(cache.parent_stack.last()).as_ref(),
);
let aliases = item.attrs.get_doc_aliases();
let is_deprecated = item.is_deprecated(tcx);
let is_unstable = item.is_unstable();
let index_item = IndexItem {
ty: item.type_(),
defid: Some(defid),
name,
module_path: parent_path.to_vec(),
desc,
parent: parent_did,
parent_idx: None,
trait_parent,
trait_parent_idx: None,
exact_module_path: None,
impl_id,
search_type,
aliases,
is_deprecated,
is_unstable,
info,
};
cache.search_index.push(index_item);
+32 -8
View File
@@ -66,7 +66,7 @@
pub(crate) use self::context::*;
pub(crate) use self::span_map::{LinkFromSrc, collect_spans_and_sources};
pub(crate) use self::write_shared::*;
use crate::clean::{self, Defaultness, ItemId, RenderedLink};
use crate::clean::{self, Defaultness, Item, ItemId, RenderedLink};
use crate::display::{Joined as _, MaybeDisplay as _};
use crate::error::Error;
use crate::formats::Impl;
@@ -79,8 +79,9 @@
print_type, print_where_clause, visibility_print_with_space,
};
use crate::html::markdown::{
HeadingOffset, IdMap, Markdown, MarkdownItemInfo, MarkdownSummaryLine,
HeadingOffset, IdMap, Markdown, MarkdownItemInfo, MarkdownSummaryLine, short_markdown_summary,
};
use crate::html::render::search_index::get_function_type_for_search;
use crate::html::static_files::SCRAPE_EXAMPLES_HELP_MD;
use crate::html::{highlight, sources};
use crate::scrape_examples::{CallData, CallLocation};
@@ -124,25 +125,48 @@ enum RenderMode {
// Helper structs for rendering items/sidebars and carrying along contextual
// information
#[derive(Debug)]
pub(crate) struct IndexItemInfo {
pub(crate) ty: ItemType,
pub(crate) desc: String,
pub(crate) search_type: Option<IndexItemFunctionType>,
pub(crate) aliases: Box<[Symbol]>,
pub(crate) deprecation: Option<Deprecation>,
pub(crate) is_unstable: bool,
}
impl IndexItemInfo {
pub(crate) fn new(
tcx: TyCtxt<'_>,
cache: &Cache,
item: &Item,
parent_did: Option<DefId>,
impl_generics: Option<&(clean::Type, clean::Generics)>,
) -> Self {
let ty = item.type_();
let desc = short_markdown_summary(&item.doc_value(), &item.link_names(cache));
let search_type = get_function_type_for_search(item, tcx, impl_generics, parent_did, cache);
let aliases = item.attrs.get_doc_aliases();
let deprecation = item.deprecation(tcx);
let is_unstable = item.is_unstable();
Self { ty, desc, search_type, aliases, deprecation, is_unstable }
}
}
/// Struct representing one entry in the JS search index. These are all emitted
/// by hand to a large JS file at the end of cache-creation.
#[derive(Debug)]
pub(crate) struct IndexItem {
pub(crate) ty: ItemType,
pub(crate) defid: Option<DefId>,
pub(crate) name: Symbol,
pub(crate) module_path: Vec<Symbol>,
pub(crate) desc: String,
pub(crate) parent: Option<DefId>,
pub(crate) parent_idx: Option<usize>,
pub(crate) trait_parent: Option<DefId>,
pub(crate) trait_parent_idx: Option<usize>,
pub(crate) exact_module_path: Option<Vec<Symbol>>,
pub(crate) impl_id: Option<DefId>,
pub(crate) search_type: Option<IndexItemFunctionType>,
pub(crate) aliases: Box<[Symbol]>,
pub(crate) is_deprecated: bool,
pub(crate) is_unstable: bool,
pub(crate) info: IndexItemInfo,
}
/// A type used for the search index.
+26 -32
View File
@@ -13,7 +13,7 @@
use rustc_ast::join_path_syms;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_data_structures::thin_vec::ThinVec;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_hir::def_id::{CrateNum, DefIndex, LOCAL_CRATE};
use rustc_hir::find_attr;
use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::DefId;
@@ -29,7 +29,9 @@
use crate::formats::cache::{Cache, OrphanImplItem};
use crate::formats::item_type::ItemType;
use crate::html::markdown::short_markdown_summary;
use crate::html::render::{self, IndexItem, IndexItemFunctionType, RenderType, RenderTypeId};
use crate::html::render::{
self, IndexItem, IndexItemFunctionType, IndexItemInfo, RenderType, RenderTypeId,
};
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub(crate) struct SerializedSearchIndex {
@@ -1270,29 +1272,18 @@ pub(crate) fn build_index(
&cache.orphan_impl_items
{
if let Some((fqp, _)) = cache.paths.get(&parent) {
let desc = short_markdown_summary(&item.doc_value(), &item.link_names(cache));
let info = IndexItemInfo::new(tcx, cache, item, Some(parent), impl_generics.as_ref());
search_index.push(IndexItem {
ty: item.type_(),
defid: item.item_id.as_def_id(),
name: item.name.unwrap(),
module_path: fqp[..fqp.len() - 1].to_vec(),
desc,
parent: Some(parent),
parent_idx: None,
trait_parent,
trait_parent_idx: None,
exact_module_path: None,
impl_id,
search_type: get_function_type_for_search(
item,
tcx,
impl_generics.as_ref(),
Some(parent),
cache,
),
aliases: item.attrs.get_doc_aliases(),
is_deprecated: item.is_deprecated(tcx),
is_unstable: item.is_unstable(),
info,
});
}
}
@@ -1301,11 +1292,10 @@ pub(crate) fn build_index(
search_index.sort_unstable_by(|k1, k2| {
// `sort_unstable_by_key` produces lifetime errors
// HACK(rustdoc): should not be sorting `CrateNum` or `DefIndex`, this will soon go away, too
let k1 =
(&k1.module_path, k1.name.as_str(), &k1.ty, k1.parent.map(|id| (id.index, id.krate)));
let k2 =
(&k2.module_path, k2.name.as_str(), &k2.ty, k2.parent.map(|id| (id.index, id.krate)));
Ord::cmp(&k1, &k2)
fn key(i: &IndexItem) -> (&[Symbol], &str, ItemType, Option<(DefIndex, CrateNum)>) {
(&i.module_path, i.name.as_str(), i.info.ty, i.parent.map(|id| (id.index, id.krate)))
}
Ord::cmp(&key(k1), &key(k2))
});
// Now, convert to an on-disk search index format
@@ -1466,7 +1456,7 @@ pub(crate) fn build_index(
if fqp.last() != Some(&item.name) {
return None;
}
let path = if item.ty == ItemType::Macro
let path = if item.info.ty == ItemType::Macro
&& find_attr!(tcx, defid, MacroExport { .. })
{
// `#[macro_export]` always exports to the crate root.
@@ -1501,8 +1491,9 @@ pub(crate) fn build_index(
if item.impl_id.is_some()
&& let Some(parent_idx) = item.parent_idx
{
let count =
associated_item_duplicates.entry((parent_idx, item.ty, item.name)).or_insert(0);
let count = associated_item_duplicates
.entry((parent_idx, item.info.ty, item.name))
.or_insert(0);
*count += 1;
}
}
@@ -1525,24 +1516,27 @@ pub(crate) fn build_index(
let new_entry_id = serialized_index.add_entry(
item.name,
EntryData {
ty: item.ty,
ty: item.info.ty,
parent: item.parent_idx,
trait_parent: item.trait_parent_idx,
module_path,
exact_module_path,
deprecated: item.is_deprecated,
unstable: item.is_unstable,
deprecated: item
.info
.deprecation
.is_some_and(|deprecation| deprecation.is_in_effect()),
unstable: item.info.is_unstable,
associated_item_disambiguator_or_extern_crate_url: if let Some(impl_id) =
item.impl_id
&& let Some(parent_idx) = item.parent_idx
&& associated_item_duplicates
.get(&(parent_idx, item.ty, item.name))
.get(&(parent_idx, item.info.ty, item.name))
.copied()
.unwrap_or(0)
> 1
{
Some(render::get_id_for_impl(tcx, ItemId::DefId(impl_id)))
} else if item.ty == ItemType::ExternCrate
} else if item.info.ty == ItemType::ExternCrate
&& let Some(local_def_id) = item.defid.and_then(|def_id| def_id.as_local())
&& let cnum = tcx.extern_mod_stmt_cnum(local_def_id).unwrap_or(LOCAL_CRATE)
&& let Some(ExternalLocation::Remote { url, is_absolute }) =
@@ -1555,12 +1549,12 @@ pub(crate) fn build_index(
},
krate: crate_idx,
},
item.desc.to_string(),
item.info.desc.to_string(),
);
// Aliases
// -------
for alias in &item.aliases[..] {
for alias in &item.info.aliases {
serialized_index.push_alias(alias.as_str().to_string(), new_entry_id);
}
@@ -1833,7 +1827,7 @@ fn convert_render_type(
_ => {}
}
}
if let Some(search_type) = &mut item.search_type {
if let Some(search_type) = &mut item.info.search_type {
let mut used_in_function_inputs = BTreeSet::new();
let mut used_in_function_output = BTreeSet::new();
for item in &mut search_type.inputs {
@@ -1900,7 +1894,7 @@ fn convert_render_type(
// The number 8 is arbitrary. We want it big, but not enormous,
// because the postings list has to fill in an empty array for each
// unoccupied size.
if item.ty.is_fn_like() { 0 } else { 16 };
if item.info.ty.is_fn_like() { 0 } else { 16 };
serialized_index.function_data[new_entry_id] = Some(search_type.clone());
#[derive(Clone, Copy)]