Skip to content

Commit 2cf6317

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 e95db59 commit 2cf6317

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
@@ -521,6 +521,7 @@ impl SerializedSearchIndex {
521521
module_path,
522522
exact_module_path,
523523
parent,
524+
trait_parent,
524525
deprecated,
525526
associated_item_disambiguator,
526527
}| EntryData {
@@ -530,6 +531,7 @@ impl SerializedSearchIndex {
530531
exact_module_path: exact_module_path
531532
.and_then(|path_id| map.get(&path_id).copied()),
532533
parent: parent.and_then(|path_id| map.get(&path_id).copied()),
534+
trait_parent: trait_parent.and_then(|path_id| map.get(&path_id).copied()),
533535
deprecated: *deprecated,
534536
associated_item_disambiguator: associated_item_disambiguator.clone(),
535537
},
@@ -788,6 +790,7 @@ struct EntryData {
788790
module_path: Option<usize>,
789791
exact_module_path: Option<usize>,
790792
parent: Option<usize>,
793+
trait_parent: Option<usize>,
791794
deprecated: bool,
792795
associated_item_disambiguator: Option<String>,
793796
}
@@ -803,6 +806,7 @@ impl Serialize for EntryData {
803806
seq.serialize_element(&self.module_path.map(|id| id + 1).unwrap_or(0))?;
804807
seq.serialize_element(&self.exact_module_path.map(|id| id + 1).unwrap_or(0))?;
805808
seq.serialize_element(&self.parent.map(|id| id + 1).unwrap_or(0))?;
809+
seq.serialize_element(&self.trait_parent.map(|id| id + 1).unwrap_or(0))?;
806810
seq.serialize_element(&if self.deprecated { 1 } else { 0 })?;
807811
if let Some(disambig) = &self.associated_item_disambiguator {
808812
seq.serialize_element(&disambig)?;
@@ -834,6 +838,9 @@ impl<'de> Deserialize<'de> for EntryData {
834838
.ok_or_else(|| A::Error::missing_field("exact_module_path"))?;
835839
let parent: SerializedOptional32 =
836840
v.next_element()?.ok_or_else(|| A::Error::missing_field("parent"))?;
841+
let trait_parent: SerializedOptional32 =
842+
v.next_element()?.ok_or_else(|| A::Error::missing_field("trait_parent"))?;
843+
837844
let deprecated: u32 = v.next_element()?.unwrap_or(0);
838845
let associated_item_disambiguator: Option<String> = v.next_element()?;
839846
Ok(EntryData {
@@ -843,6 +850,7 @@ impl<'de> Deserialize<'de> for EntryData {
843850
exact_module_path: Option::<i32>::from(exact_module_path)
844851
.map(|path| path as usize),
845852
parent: Option::<i32>::from(parent).map(|path| path as usize),
853+
trait_parent: Option::<i32>::from(trait_parent).map(|path| path as usize),
846854
deprecated: deprecated != 0,
847855
associated_item_disambiguator,
848856
})
@@ -1167,7 +1175,8 @@ pub(crate) fn build_index(
11671175

11681176
// Attach all orphan items to the type's definition if the type
11691177
// has since been learned.
1170-
for &OrphanImplItem { impl_id, parent, ref item, ref impl_generics } in &cache.orphan_impl_items
1178+
for &OrphanImplItem { impl_id, parent, trait_parent, ref item, ref impl_generics } in
1179+
&cache.orphan_impl_items
11711180
{
11721181
if let Some((fqp, _)) = cache.paths.get(&parent) {
11731182
let desc = short_markdown_summary(&item.doc_value(), &item.link_names(cache));
@@ -1179,6 +1188,8 @@ pub(crate) fn build_index(
11791188
desc,
11801189
parent: Some(parent),
11811190
parent_idx: None,
1191+
trait_parent,
1192+
trait_parent_idx: None,
11821193
exact_module_path: None,
11831194
impl_id,
11841195
search_type: get_function_type_for_search(
@@ -1275,6 +1286,7 @@ pub(crate) fn build_index(
12751286
module_path: None,
12761287
exact_module_path: None,
12771288
parent: None,
1289+
trait_parent: None,
12781290
deprecated: false,
12791291
associated_item_disambiguator: None,
12801292
}),
@@ -1288,39 +1300,46 @@ pub(crate) fn build_index(
12881300
}
12891301
};
12901302

1291-
// First, populate associated item parents
1303+
// First, populate associated item parents and trait parents
12921304
let crate_items: Vec<&mut IndexItem> = search_index
12931305
.iter_mut()
12941306
.map(|item| {
1295-
item.parent_idx = item.parent.and_then(|defid| {
1296-
cache.paths.get(&defid).map(|&(ref fqp, ty)| {
1297-
let pathid = serialized_index.names.len();
1298-
match serialized_index.crate_paths_index.entry((ty, fqp.clone())) {
1299-
Entry::Occupied(entry) => *entry.get(),
1300-
Entry::Vacant(entry) => {
1301-
entry.insert(pathid);
1302-
let (name, path) = fqp.split_last().unwrap();
1303-
serialized_index.push_path(
1304-
name.as_str().to_string(),
1305-
PathData {
1306-
ty,
1307-
module_path: path.to_vec(),
1308-
exact_module_path: if let Some(exact_path) =
1309-
cache.exact_paths.get(&defid)
1310-
&& let Some((name2, exact_path)) = exact_path.split_last()
1311-
&& name == name2
1312-
{
1313-
Some(exact_path.to_vec())
1314-
} else {
1315-
None
1307+
let mut defid_to_rowid = |defid, check_external: bool| {
1308+
cache
1309+
.paths
1310+
.get(&defid)
1311+
.or_else(|| check_external.then(|| cache.external_paths.get(&defid)).flatten())
1312+
.map(|&(ref fqp, ty)| {
1313+
let pathid = serialized_index.names.len();
1314+
match serialized_index.crate_paths_index.entry((ty, fqp.clone())) {
1315+
Entry::Occupied(entry) => *entry.get(),
1316+
Entry::Vacant(entry) => {
1317+
entry.insert(pathid);
1318+
let (name, path) = fqp.split_last().unwrap();
1319+
serialized_index.push_path(
1320+
name.as_str().to_string(),
1321+
PathData {
1322+
ty,
1323+
module_path: path.to_vec(),
1324+
exact_module_path: if let Some(exact_path) =
1325+
cache.exact_paths.get(&defid)
1326+
&& let Some((name2, exact_path)) =
1327+
exact_path.split_last()
1328+
&& name == name2
1329+
{
1330+
Some(exact_path.to_vec())
1331+
} else {
1332+
None
1333+
},
13161334
},
1317-
},
1318-
);
1319-
usize::try_from(pathid).unwrap()
1335+
);
1336+
usize::try_from(pathid).unwrap()
1337+
}
13201338
}
1321-
}
1322-
})
1323-
});
1339+
})
1340+
};
1341+
item.parent_idx = item.parent.and_then(|p| defid_to_rowid(p, false));
1342+
item.trait_parent_idx = item.trait_parent.and_then(|p| defid_to_rowid(p, true));
13241343

13251344
if let Some(defid) = item.defid
13261345
&& item.parent_idx.is_none()
@@ -1403,6 +1422,7 @@ pub(crate) fn build_index(
14031422
Some(EntryData {
14041423
ty: item.ty,
14051424
parent: item.parent_idx,
1425+
trait_parent: item.trait_parent_idx,
14061426
module_path,
14071427
exact_module_path,
14081428
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
}
@@ -288,9 +289,12 @@ declare namespace rustdoc {
288289
path: PathData?,
289290
type: FunctionData?,
290291
deprecated: boolean,
291-
parent: { path: PathData, name: string}?,
292+
parent: RowParent,
293+
traitParent: RowParent,
292294
}
293295

296+
type RowParent = { path: PathData, name: string } | null;
297+
294298
type ItemType = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
295299
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
296300
21 | 22 | 23 | 24 | 25 | 26;
@@ -313,7 +317,23 @@ declare namespace rustdoc {
313317
interface ResultObject {
314318
desc: Promise<string|null>,
315319
displayPath: string,
320+
/**
321+
* path to where the item was defined (not inlined),
322+
* then `|`, then the `ItemType` of the item.
323+
*
324+
* This is often a private path, so it should not be displayed,
325+
* but this allows us to use it to reliably deduplicate reexported and inlined items
326+
*/
316327
fullPath: string,
328+
/**
329+
* The `fullPath` of the corresponding item within a trait.
330+
* For example, for `File::read`, this would be `std::io::Read::read|12`
331+
*
332+
* This is used to hide items from trait impls when the trait itself is in the search results.
333+
*
334+
* `null` if the item is not from a trait impl block.
335+
*/
336+
traitPath: string | null,
317337
href: string,
318338
id: number,
319339
dist: number,

0 commit comments

Comments
 (0)