Skip to content

Commit c979014

Browse files
committed
if a trait item is shown in search results, hide the impl item
for example, if we're showing `Iterator::next`, we don't need to also show `Range::next` in the results.
1 parent fd75a9c commit c979014

File tree

5 files changed

+167
-54
lines changed

5 files changed

+167
-54
lines changed

src/librustdoc/formats/cache.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,14 @@ impl Cache {
148148
Cache { document_private, document_hidden, ..Cache::default() }
149149
}
150150

151+
fn parent_stack_last_impl_and_trait_id(&self) -> (Option<DefId>, Option<DefId>) {
152+
if let Some(ParentStackItem::Impl { item_id, trait_, .. }) = self.parent_stack.last() {
153+
(item_id.as_def_id(), trait_.as_ref().map(|tr| tr.def_id()))
154+
} else {
155+
(None, None)
156+
}
157+
}
158+
151159
/// Populates the `Cache` with more data. The returned `Crate` will be missing some data that was
152160
/// in `krate` due to the data being moved into the `Cache`.
153161
pub(crate) fn populate(cx: &mut DocContext<'_>, mut krate: clean::Crate) -> clean::Crate {
@@ -574,11 +582,7 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It
574582
clean::ItemKind::ImportItem(import) => import.source.did.unwrap_or(item_def_id),
575583
_ => item_def_id,
576584
};
577-
let impl_id = if let Some(ParentStackItem::Impl { item_id, .. }) = cache.parent_stack.last() {
578-
item_id.as_def_id()
579-
} else {
580-
None
581-
};
585+
let (impl_id, trait_parent) = cache.parent_stack_last_impl_and_trait_id();
582586
let search_type = get_function_type_for_search(
583587
item,
584588
tcx,
@@ -596,12 +600,15 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It
596600
desc,
597601
parent: parent_did,
598602
parent_idx: None,
603+
trait_parent,
604+
trait_parent_idx: None,
599605
exact_module_path: None,
600606
impl_id,
601607
search_type,
602608
aliases,
603609
deprecation,
604610
};
611+
605612
cache.search_index.push(index_item);
606613
}
607614

@@ -610,19 +617,21 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It
610617
/// See [`Cache::orphan_impl_items`].
611618
fn handle_orphan_impl_child(cache: &mut Cache, item: &clean::Item, parent_did: DefId) {
612619
let impl_generics = clean_impl_generics(cache.parent_stack.last());
613-
let impl_id = if let Some(ParentStackItem::Impl { item_id, .. }) = cache.parent_stack.last() {
614-
item_id.as_def_id()
615-
} else {
616-
None
620+
let (impl_id, trait_parent) = cache.parent_stack_last_impl_and_trait_id();
621+
let orphan_item = OrphanImplItem {
622+
parent: parent_did,
623+
trait_parent,
624+
item: item.clone(),
625+
impl_generics,
626+
impl_id,
617627
};
618-
let orphan_item =
619-
OrphanImplItem { parent: parent_did, item: item.clone(), impl_generics, impl_id };
620628
cache.orphan_impl_items.push(orphan_item);
621629
}
622630

623631
pub(crate) struct OrphanImplItem {
624632
pub(crate) parent: DefId,
625633
pub(crate) impl_id: Option<DefId>,
634+
pub(crate) trait_parent: Option<DefId>,
626635
pub(crate) item: clean::Item,
627636
pub(crate) impl_generics: Option<(clean::Type, clean::Generics)>,
628637
}

src/librustdoc/html/render/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ pub(crate) struct IndexItem {
134134
pub(crate) desc: String,
135135
pub(crate) parent: Option<DefId>,
136136
pub(crate) parent_idx: Option<usize>,
137+
pub(crate) trait_parent: Option<DefId>,
138+
pub(crate) trait_parent_idx: Option<usize>,
137139
pub(crate) exact_module_path: Option<Vec<Symbol>>,
138140
pub(crate) impl_id: Option<DefId>,
139141
pub(crate) search_type: Option<IndexItemFunctionType>,

src/librustdoc/html/render/search_index.rs

Lines changed: 49 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,7 @@ impl SerializedSearchIndex {
580580
module_path,
581581
exact_module_path,
582582
parent,
583+
trait_parent,
583584
deprecated,
584585
associated_item_disambiguator,
585586
}| EntryData {
@@ -589,6 +590,7 @@ impl SerializedSearchIndex {
589590
exact_module_path: exact_module_path
590591
.and_then(|path_id| map.get(&path_id).copied()),
591592
parent: parent.and_then(|path_id| map.get(&path_id).copied()),
593+
trait_parent: trait_parent.and_then(|path_id| map.get(&path_id).copied()),
592594
deprecated: *deprecated,
593595
associated_item_disambiguator: associated_item_disambiguator.clone(),
594596
},
@@ -870,6 +872,7 @@ struct EntryData {
870872
module_path: Option<usize>,
871873
exact_module_path: Option<usize>,
872874
parent: Option<usize>,
875+
trait_parent: Option<usize>,
873876
deprecated: bool,
874877
associated_item_disambiguator: Option<String>,
875878
}
@@ -885,6 +888,7 @@ impl Serialize for EntryData {
885888
seq.serialize_element(&self.module_path.map(|id| id + 1).unwrap_or(0))?;
886889
seq.serialize_element(&self.exact_module_path.map(|id| id + 1).unwrap_or(0))?;
887890
seq.serialize_element(&self.parent.map(|id| id + 1).unwrap_or(0))?;
891+
seq.serialize_element(&self.trait_parent.map(|id| id + 1).unwrap_or(0))?;
888892
seq.serialize_element(&if self.deprecated { 1 } else { 0 })?;
889893
if let Some(disambig) = &self.associated_item_disambiguator {
890894
seq.serialize_element(&disambig)?;
@@ -916,6 +920,9 @@ impl<'de> Deserialize<'de> for EntryData {
916920
.ok_or_else(|| A::Error::missing_field("exact_module_path"))?;
917921
let parent: SerializedOptional32 =
918922
v.next_element()?.ok_or_else(|| A::Error::missing_field("parent"))?;
923+
let trait_parent: SerializedOptional32 =
924+
v.next_element()?.ok_or_else(|| A::Error::missing_field("trait_parent"))?;
925+
919926
let deprecated: u32 = v.next_element()?.unwrap_or(0);
920927
let associated_item_disambiguator: Option<String> = v.next_element()?;
921928
Ok(EntryData {
@@ -925,6 +932,7 @@ impl<'de> Deserialize<'de> for EntryData {
925932
exact_module_path: Option::<i32>::from(exact_module_path)
926933
.map(|path| path as usize),
927934
parent: Option::<i32>::from(parent).map(|path| path as usize),
935+
trait_parent: Option::<i32>::from(trait_parent).map(|path| path as usize),
928936
deprecated: deprecated != 0,
929937
associated_item_disambiguator,
930938
})
@@ -1275,7 +1283,8 @@ pub(crate) fn build_index(
12751283

12761284
// Attach all orphan items to the type's definition if the type
12771285
// has since been learned.
1278-
for &OrphanImplItem { impl_id, parent, ref item, ref impl_generics } in &cache.orphan_impl_items
1286+
for &OrphanImplItem { impl_id, parent, trait_parent, ref item, ref impl_generics } in
1287+
&cache.orphan_impl_items
12791288
{
12801289
if let Some((fqp, _)) = cache.paths.get(&parent) {
12811290
let desc = short_markdown_summary(&item.doc_value(), &item.link_names(cache));
@@ -1287,6 +1296,8 @@ pub(crate) fn build_index(
12871296
desc,
12881297
parent: Some(parent),
12891298
parent_idx: None,
1299+
trait_parent,
1300+
trait_parent_idx: None,
12901301
exact_module_path: None,
12911302
impl_id,
12921303
search_type: get_function_type_for_search(
@@ -1391,6 +1402,7 @@ pub(crate) fn build_index(
13911402
module_path: None,
13921403
exact_module_path: None,
13931404
parent: None,
1405+
trait_parent: None,
13941406
deprecated: false,
13951407
associated_item_disambiguator: None,
13961408
}),
@@ -1404,39 +1416,46 @@ pub(crate) fn build_index(
14041416
}
14051417
};
14061418

1407-
// First, populate associated item parents
1419+
// First, populate associated item parents and trait parents
14081420
let crate_items: Vec<&mut IndexItem> = search_index
14091421
.iter_mut()
14101422
.map(|item| {
1411-
item.parent_idx = item.parent.and_then(|defid| {
1412-
cache.paths.get(&defid).map(|&(ref fqp, ty)| {
1413-
let pathid = serialized_index.names.len();
1414-
match serialized_index.crate_paths_index.entry((ty, fqp.clone())) {
1415-
Entry::Occupied(entry) => *entry.get(),
1416-
Entry::Vacant(entry) => {
1417-
entry.insert(pathid);
1418-
let (name, path) = fqp.split_last().unwrap();
1419-
serialized_index.push_path(
1420-
name.as_str().to_string(),
1421-
PathData {
1422-
ty,
1423-
module_path: path.to_vec(),
1424-
exact_module_path: if let Some(exact_path) =
1425-
cache.exact_paths.get(&defid)
1426-
&& let Some((name2, exact_path)) = exact_path.split_last()
1427-
&& name == name2
1428-
{
1429-
Some(exact_path.to_vec())
1430-
} else {
1431-
None
1423+
let mut defid_to_rowid = |defid, check_external: bool| {
1424+
cache
1425+
.paths
1426+
.get(&defid)
1427+
.or_else(|| check_external.then(|| cache.external_paths.get(&defid)).flatten())
1428+
.map(|&(ref fqp, ty)| {
1429+
let pathid = serialized_index.names.len();
1430+
match serialized_index.crate_paths_index.entry((ty, fqp.clone())) {
1431+
Entry::Occupied(entry) => *entry.get(),
1432+
Entry::Vacant(entry) => {
1433+
entry.insert(pathid);
1434+
let (name, path) = fqp.split_last().unwrap();
1435+
serialized_index.push_path(
1436+
name.as_str().to_string(),
1437+
PathData {
1438+
ty,
1439+
module_path: path.to_vec(),
1440+
exact_module_path: if let Some(exact_path) =
1441+
cache.exact_paths.get(&defid)
1442+
&& let Some((name2, exact_path)) =
1443+
exact_path.split_last()
1444+
&& name == name2
1445+
{
1446+
Some(exact_path.to_vec())
1447+
} else {
1448+
None
1449+
},
14321450
},
1433-
},
1434-
);
1435-
usize::try_from(pathid).unwrap()
1451+
);
1452+
usize::try_from(pathid).unwrap()
1453+
}
14361454
}
1437-
}
1438-
})
1439-
});
1455+
})
1456+
};
1457+
item.parent_idx = item.parent.and_then(|p| defid_to_rowid(p, false));
1458+
item.trait_parent_idx = item.trait_parent.and_then(|p| defid_to_rowid(p, true));
14401459

14411460
if let Some(defid) = item.defid
14421461
&& item.parent_idx.is_none()
@@ -1519,6 +1538,7 @@ pub(crate) fn build_index(
15191538
Some(EntryData {
15201539
ty: item.ty,
15211540
parent: item.parent_idx,
1541+
trait_parent: item.trait_parent_idx,
15221542
module_path,
15231543
exact_module_path,
15241544
deprecated: item.deprecation.is_some(),

src/librustdoc/html/static/js/rustdoc.d.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ declare namespace rustdoc {
241241
modulePath: number?,
242242
exactModulePath: number?,
243243
parent: number?,
244+
traitParent: number?,
244245
deprecated: boolean,
245246
associatedItemDisambiguator: string?,
246247
}
@@ -291,9 +292,12 @@ declare namespace rustdoc {
291292
path: PathData?,
292293
functionData: FunctionData?,
293294
deprecated: boolean,
294-
parent: { path: PathData, name: string}?,
295+
parent: RowParent,
296+
traitParent: RowParent,
295297
}
296298

299+
type RowParent = { path: PathData, name: string } | null;
300+
297301
type ItemType = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
298302
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
299303
21 | 22 | 23 | 24 | 25 | 26;
@@ -316,7 +320,23 @@ declare namespace rustdoc {
316320
interface ResultObject {
317321
desc: Promise<string|null>,
318322
displayPath: string,
323+
/**
324+
* path to where the item was defined (not inlined),
325+
* then `|`, then the `ItemType` of the item.
326+
*
327+
* This is often a private path, so it should not be displayed,
328+
* but this allows us to use it to reliably deduplicate reexported and inlined items
329+
*/
319330
fullPath: string,
331+
/**
332+
* The `fullPath` of the corresponding item within a trait.
333+
* For example, for `File::read`, this would be `std::io::Read::read|12`
334+
*
335+
* This is used to hide items from trait impls when the trait itself is in the search results.
336+
*
337+
* `null` if the item is not from a trait impl block.
338+
*/
339+
traitPath: string | null,
320340
href: string,
321341
id: number,
322342
dist: number,

0 commit comments

Comments
 (0)