Skip to content

Commit 7dd5ad2

Browse files
committed
rustdoc: Extract helper function to add item to search index
1 parent 83dcdb3 commit 7dd5ad2

File tree

1 file changed

+135
-137
lines changed

1 file changed

+135
-137
lines changed

src/librustdoc/formats/cache.rs

Lines changed: 135 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
260260
}
261261

262262
// Index this method for searching later on.
263-
if let Some(s) = item.name.or_else(|| {
263+
if let Some(name) = item.name.or_else(|| {
264264
if item.is_stripped() {
265265
None
266266
} else if let clean::ImportItem(ref i) = *item.kind
@@ -271,142 +271,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
271271
None
272272
}
273273
}) {
274-
let (parent, is_inherent_impl_item) = match *item.kind {
275-
clean::StrippedItem(..) => ((None, None), false),
276-
clean::AssocConstItem(..) | clean::AssocTypeItem(..)
277-
if self
278-
.cache
279-
.parent_stack
280-
.last()
281-
.is_some_and(|parent| parent.is_trait_impl()) =>
282-
{
283-
// skip associated items in trait impls
284-
((None, None), false)
285-
}
286-
clean::TyMethodItem(..)
287-
| clean::TyAssocConstItem(..)
288-
| clean::TyAssocTypeItem(..)
289-
| clean::StructFieldItem(..)
290-
| clean::VariantItem(..) => (
291-
(
292-
Some(
293-
self.cache
294-
.parent_stack
295-
.last()
296-
.expect("parent_stack is empty")
297-
.item_id()
298-
.expect_def_id(),
299-
),
300-
Some(&self.cache.stack[..self.cache.stack.len() - 1]),
301-
),
302-
false,
303-
),
304-
clean::MethodItem(..) | clean::AssocConstItem(..) | clean::AssocTypeItem(..) => {
305-
if self.cache.parent_stack.is_empty() {
306-
((None, None), false)
307-
} else {
308-
let last = self.cache.parent_stack.last().expect("parent_stack is empty 2");
309-
let did = match &*last {
310-
ParentStackItem::Impl {
311-
// impl Trait for &T { fn method(self); }
312-
//
313-
// When generating a function index with the above shape, we want it
314-
// associated with `T`, not with the primitive reference type. It should
315-
// show up as `T::method`, rather than `reference::method`, in the search
316-
// results page.
317-
for_: clean::Type::BorrowedRef { type_, .. },
318-
..
319-
} => type_.def_id(&self.cache),
320-
ParentStackItem::Impl { for_, .. } => for_.def_id(&self.cache),
321-
ParentStackItem::Type(item_id) => item_id.as_def_id(),
322-
};
323-
let path = did
324-
.and_then(|did| self.cache.paths.get(&did))
325-
// The current stack not necessarily has correlation
326-
// for where the type was defined. On the other
327-
// hand, `paths` always has the right
328-
// information if present.
329-
.map(|(fqp, _)| &fqp[..fqp.len() - 1]);
330-
((did, path), true)
331-
}
332-
}
333-
_ => ((None, Some(&*self.cache.stack)), false),
334-
};
335-
336-
match parent {
337-
(parent, Some(path)) if is_inherent_impl_item || !self.cache.stripped_mod => {
338-
debug_assert!(!item.is_stripped());
339-
340-
// A crate has a module at its root, containing all items,
341-
// which should not be indexed. The crate-item itself is
342-
// inserted later on when serializing the search-index.
343-
if item.item_id.as_def_id().is_some_and(|idx| !idx.is_crate_root())
344-
&& let ty = item.type_()
345-
&& (ty != ItemType::StructField
346-
|| u16::from_str_radix(s.as_str(), 10).is_err())
347-
{
348-
let desc =
349-
short_markdown_summary(&item.doc_value(), &item.link_names(self.cache));
350-
// For searching purposes, a re-export is a duplicate if:
351-
//
352-
// - It's either an inline, or a true re-export
353-
// - It's got the same name
354-
// - Both of them have the same exact path
355-
let defid = (match &*item.kind {
356-
&clean::ItemKind::ImportItem(ref import) => import.source.did,
357-
_ => None,
358-
})
359-
.or_else(|| item.item_id.as_def_id());
360-
// In case this is a field from a tuple struct, we don't add it into
361-
// the search index because its name is something like "0", which is
362-
// not useful for rustdoc search.
363-
self.cache.search_index.push(IndexItem {
364-
ty,
365-
defid,
366-
name: s,
367-
path: join_with_double_colon(path),
368-
desc,
369-
parent,
370-
parent_idx: None,
371-
exact_path: None,
372-
impl_id: if let Some(ParentStackItem::Impl { item_id, .. }) =
373-
self.cache.parent_stack.last()
374-
{
375-
item_id.as_def_id()
376-
} else {
377-
None
378-
},
379-
search_type: get_function_type_for_search(
380-
&item,
381-
self.tcx,
382-
clean_impl_generics(self.cache.parent_stack.last()).as_ref(),
383-
parent,
384-
self.cache,
385-
),
386-
aliases: item.attrs.get_doc_aliases(),
387-
deprecation: item.deprecation(self.tcx),
388-
});
389-
}
390-
}
391-
(Some(parent), None) if is_inherent_impl_item => {
392-
// We have a parent, but we don't know where they're
393-
// defined yet. Wait for later to index this item.
394-
let impl_generics = clean_impl_generics(self.cache.parent_stack.last());
395-
self.cache.orphan_impl_items.push(OrphanImplItem {
396-
parent,
397-
item: item.clone(),
398-
impl_generics,
399-
impl_id: if let Some(ParentStackItem::Impl { item_id, .. }) =
400-
self.cache.parent_stack.last()
401-
{
402-
item_id.as_def_id()
403-
} else {
404-
None
405-
},
406-
});
407-
}
408-
_ => {}
409-
}
274+
add_item_to_search_index(self.tcx, &mut self.cache, &item, name)
410275
}
411276

412277
// Keep track of the fully qualified path for this item.
@@ -573,6 +438,139 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
573438
}
574439
}
575440

441+
fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::Item, name: Symbol) {
442+
let (parent, is_inherent_impl_item) = match *item.kind {
443+
clean::StrippedItem(..) => ((None, None), false),
444+
clean::AssocConstItem(..) | clean::AssocTypeItem(..)
445+
if cache.parent_stack.last().is_some_and(|parent| parent.is_trait_impl()) =>
446+
{
447+
// skip associated items in trait impls
448+
((None, None), false)
449+
}
450+
clean::TyMethodItem(..)
451+
| clean::TyAssocConstItem(..)
452+
| clean::TyAssocTypeItem(..)
453+
| clean::StructFieldItem(..)
454+
| clean::VariantItem(..) => (
455+
(
456+
Some(
457+
cache
458+
.parent_stack
459+
.last()
460+
.expect("parent_stack is empty")
461+
.item_id()
462+
.expect_def_id(),
463+
),
464+
Some(&cache.stack[..cache.stack.len() - 1]),
465+
),
466+
false,
467+
),
468+
clean::MethodItem(..) | clean::AssocConstItem(..) | clean::AssocTypeItem(..) => {
469+
if cache.parent_stack.is_empty() {
470+
((None, None), false)
471+
} else {
472+
let last = cache.parent_stack.last().expect("parent_stack is empty 2");
473+
let did = match &*last {
474+
ParentStackItem::Impl {
475+
// impl Trait for &T { fn method(self); }
476+
//
477+
// When generating a function index with the above shape, we want it
478+
// associated with `T`, not with the primitive reference type. It should
479+
// show up as `T::method`, rather than `reference::method`, in the search
480+
// results page.
481+
for_: clean::Type::BorrowedRef { type_, .. },
482+
..
483+
} => type_.def_id(&cache),
484+
ParentStackItem::Impl { for_, .. } => for_.def_id(&cache),
485+
ParentStackItem::Type(item_id) => item_id.as_def_id(),
486+
};
487+
let path = did
488+
.and_then(|did| cache.paths.get(&did))
489+
// The current stack not necessarily has correlation
490+
// for where the type was defined. On the other
491+
// hand, `paths` always has the right
492+
// information if present.
493+
.map(|(fqp, _)| &fqp[..fqp.len() - 1]);
494+
((did, path), true)
495+
}
496+
}
497+
_ => ((None, Some(&*cache.stack)), false),
498+
};
499+
500+
match parent {
501+
(parent, Some(path)) if is_inherent_impl_item || !cache.stripped_mod => {
502+
debug_assert!(!item.is_stripped());
503+
504+
// A crate has a module at its root, containing all items,
505+
// which should not be indexed. The crate-item itself is
506+
// inserted later on when serializing the search-index.
507+
if item.item_id.as_def_id().is_some_and(|idx| !idx.is_crate_root())
508+
&& let ty = item.type_()
509+
&& (ty != ItemType::StructField || u16::from_str_radix(name.as_str(), 10).is_err())
510+
{
511+
let desc = short_markdown_summary(&item.doc_value(), &item.link_names(cache));
512+
// For searching purposes, a re-export is a duplicate if:
513+
//
514+
// - It's either an inline, or a true re-export
515+
// - It's got the same name
516+
// - Both of them have the same exact path
517+
let defid = (match &*item.kind {
518+
&clean::ItemKind::ImportItem(ref import) => import.source.did,
519+
_ => None,
520+
})
521+
.or_else(|| item.item_id.as_def_id());
522+
// In case this is a field from a tuple struct, we don't add it into
523+
// the search index because its name is something like "0", which is
524+
// not useful for rustdoc search.
525+
cache.search_index.push(IndexItem {
526+
ty,
527+
defid,
528+
name,
529+
path: join_with_double_colon(path),
530+
desc,
531+
parent,
532+
parent_idx: None,
533+
exact_path: None,
534+
impl_id: if let Some(ParentStackItem::Impl { item_id, .. }) =
535+
cache.parent_stack.last()
536+
{
537+
item_id.as_def_id()
538+
} else {
539+
None
540+
},
541+
search_type: get_function_type_for_search(
542+
&item,
543+
tcx,
544+
clean_impl_generics(cache.parent_stack.last()).as_ref(),
545+
parent,
546+
cache,
547+
),
548+
aliases: item.attrs.get_doc_aliases(),
549+
deprecation: item.deprecation(tcx),
550+
});
551+
}
552+
}
553+
(Some(parent), None) if is_inherent_impl_item => {
554+
// We have a parent, but we don't know where they're
555+
// defined yet. Wait for later to index this item.
556+
let impl_generics = clean_impl_generics(cache.parent_stack.last());
557+
cache.orphan_impl_items.push(OrphanImplItem {
558+
parent,
559+
item: item.clone(),
560+
impl_generics,
561+
impl_id: if let Some(ParentStackItem::Impl { item_id, .. }) =
562+
cache.parent_stack.last()
563+
{
564+
item_id.as_def_id()
565+
} else {
566+
None
567+
},
568+
});
569+
}
570+
_ => {}
571+
}
572+
}
573+
576574
pub(crate) struct OrphanImplItem {
577575
pub(crate) parent: DefId,
578576
pub(crate) impl_id: Option<DefId>,

0 commit comments

Comments
 (0)