Skip to content

Commit dd09100

Browse files
committed
Auto merge of #145898 - lolbinarycat:rustdoc-search-trait-parent, r=GuillaumeGomez,notriddle
If a trait item appears in rustdoc search, hide the corrosponding impl items fixes #138251 cc `@notriddle`
2 parents 3b8665c + c7d6857 commit dd09100

File tree

14 files changed

+275
-96
lines changed

14 files changed

+275
-96
lines changed

src/ci/docker/host-x86_64/pr-check-2/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ ENV SCRIPT \
3232
python3 ../x.py clippy ci --stage 2 && \
3333
python3 ../x.py test --stage 1 core alloc std test proc_macro && \
3434
python3 ../x.py test --stage 1 src/tools/compiletest && \
35-
python3 ../x.py doc bootstrap && \
35+
python3 ../x.py doc bootstrap --stage 1 && \
3636
# Build both public and internal documentation.
3737
RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc compiler --stage 1 && \
3838
RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc library --stage 1 && \

src/librustdoc/formats/cache.rs

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

149+
fn parent_stack_last_impl_and_trait_id(&self) -> (Option<DefId>, Option<DefId>) {
150+
if let Some(ParentStackItem::Impl { item_id, trait_, .. }) = self.parent_stack.last() {
151+
(item_id.as_def_id(), trait_.as_ref().map(|tr| tr.def_id()))
152+
} else {
153+
(None, None)
154+
}
155+
}
156+
149157
/// Populates the `Cache` with more data. The returned `Crate` will be missing some data that was
150158
/// in `krate` due to the data being moved into the `Cache`.
151159
pub(crate) fn populate(cx: &mut DocContext<'_>, mut krate: clean::Crate) -> clean::Crate {
@@ -572,11 +580,7 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It
572580
clean::ItemKind::ImportItem(import) => import.source.did.unwrap_or(item_def_id),
573581
_ => item_def_id,
574582
};
575-
let impl_id = if let Some(ParentStackItem::Impl { item_id, .. }) = cache.parent_stack.last() {
576-
item_id.as_def_id()
577-
} else {
578-
None
579-
};
583+
let (impl_id, trait_parent) = cache.parent_stack_last_impl_and_trait_id();
580584
let search_type = get_function_type_for_search(
581585
item,
582586
tcx,
@@ -594,12 +598,15 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It
594598
desc,
595599
parent: parent_did,
596600
parent_idx: None,
601+
trait_parent,
602+
trait_parent_idx: None,
597603
exact_module_path: None,
598604
impl_id,
599605
search_type,
600606
aliases,
601607
deprecation,
602608
};
609+
603610
cache.search_index.push(index_item);
604611
}
605612

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

621629
pub(crate) struct OrphanImplItem {
622630
pub(crate) parent: DefId,
623631
pub(crate) impl_id: Option<DefId>,
632+
pub(crate) trait_parent: Option<DefId>,
624633
pub(crate) item: clean::Item,
625634
pub(crate) impl_generics: Option<(clean::Type, clean::Generics)>,
626635
}

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
@@ -610,6 +610,7 @@ impl SerializedSearchIndex {
610610
module_path,
611611
exact_module_path,
612612
parent,
613+
trait_parent,
613614
deprecated,
614615
associated_item_disambiguator,
615616
}| EntryData {
@@ -619,6 +620,7 @@ impl SerializedSearchIndex {
619620
exact_module_path: exact_module_path
620621
.and_then(|path_id| map.get(&path_id).copied()),
621622
parent: parent.and_then(|path_id| map.get(&path_id).copied()),
623+
trait_parent: trait_parent.and_then(|path_id| map.get(&path_id).copied()),
622624
deprecated: *deprecated,
623625
associated_item_disambiguator: associated_item_disambiguator.clone(),
624626
},
@@ -900,6 +902,7 @@ struct EntryData {
900902
module_path: Option<usize>,
901903
exact_module_path: Option<usize>,
902904
parent: Option<usize>,
905+
trait_parent: Option<usize>,
903906
deprecated: bool,
904907
associated_item_disambiguator: Option<String>,
905908
}
@@ -915,6 +918,7 @@ impl Serialize for EntryData {
915918
seq.serialize_element(&self.module_path.map(|id| id + 1).unwrap_or(0))?;
916919
seq.serialize_element(&self.exact_module_path.map(|id| id + 1).unwrap_or(0))?;
917920
seq.serialize_element(&self.parent.map(|id| id + 1).unwrap_or(0))?;
921+
seq.serialize_element(&self.trait_parent.map(|id| id + 1).unwrap_or(0))?;
918922
seq.serialize_element(&if self.deprecated { 1 } else { 0 })?;
919923
if let Some(disambig) = &self.associated_item_disambiguator {
920924
seq.serialize_element(&disambig)?;
@@ -946,6 +950,9 @@ impl<'de> Deserialize<'de> for EntryData {
946950
.ok_or_else(|| A::Error::missing_field("exact_module_path"))?;
947951
let parent: SerializedOptional32 =
948952
v.next_element()?.ok_or_else(|| A::Error::missing_field("parent"))?;
953+
let trait_parent: SerializedOptional32 =
954+
v.next_element()?.ok_or_else(|| A::Error::missing_field("trait_parent"))?;
955+
949956
let deprecated: u32 = v.next_element()?.unwrap_or(0);
950957
let associated_item_disambiguator: Option<String> = v.next_element()?;
951958
Ok(EntryData {
@@ -955,6 +962,7 @@ impl<'de> Deserialize<'de> for EntryData {
955962
exact_module_path: Option::<i32>::from(exact_module_path)
956963
.map(|path| path as usize),
957964
parent: Option::<i32>::from(parent).map(|path| path as usize),
965+
trait_parent: Option::<i32>::from(trait_parent).map(|path| path as usize),
958966
deprecated: deprecated != 0,
959967
associated_item_disambiguator,
960968
})
@@ -1305,7 +1313,8 @@ pub(crate) fn build_index(
13051313

13061314
// Attach all orphan items to the type's definition if the type
13071315
// has since been learned.
1308-
for &OrphanImplItem { impl_id, parent, ref item, ref impl_generics } in &cache.orphan_impl_items
1316+
for &OrphanImplItem { impl_id, parent, trait_parent, ref item, ref impl_generics } in
1317+
&cache.orphan_impl_items
13091318
{
13101319
if let Some((fqp, _)) = cache.paths.get(&parent) {
13111320
let desc = short_markdown_summary(&item.doc_value(), &item.link_names(cache));
@@ -1317,6 +1326,8 @@ pub(crate) fn build_index(
13171326
desc,
13181327
parent: Some(parent),
13191328
parent_idx: None,
1329+
trait_parent,
1330+
trait_parent_idx: None,
13201331
exact_module_path: None,
13211332
impl_id,
13221333
search_type: get_function_type_for_search(
@@ -1421,6 +1432,7 @@ pub(crate) fn build_index(
14211432
module_path: None,
14221433
exact_module_path: None,
14231434
parent: None,
1435+
trait_parent: None,
14241436
deprecated: false,
14251437
associated_item_disambiguator: None,
14261438
}),
@@ -1434,39 +1446,46 @@ pub(crate) fn build_index(
14341446
}
14351447
};
14361448

1437-
// First, populate associated item parents
1449+
// First, populate associated item parents and trait parents
14381450
let crate_items: Vec<&mut IndexItem> = search_index
14391451
.iter_mut()
14401452
.map(|item| {
1441-
item.parent_idx = item.parent.and_then(|defid| {
1442-
cache.paths.get(&defid).map(|&(ref fqp, ty)| {
1443-
let pathid = serialized_index.names.len();
1444-
match serialized_index.crate_paths_index.entry((ty, fqp.clone())) {
1445-
Entry::Occupied(entry) => *entry.get(),
1446-
Entry::Vacant(entry) => {
1447-
entry.insert(pathid);
1448-
let (name, path) = fqp.split_last().unwrap();
1449-
serialized_index.push_path(
1450-
name.as_str().to_string(),
1451-
PathData {
1452-
ty,
1453-
module_path: path.to_vec(),
1454-
exact_module_path: if let Some(exact_path) =
1455-
cache.exact_paths.get(&defid)
1456-
&& let Some((name2, exact_path)) = exact_path.split_last()
1457-
&& name == name2
1458-
{
1459-
Some(exact_path.to_vec())
1460-
} else {
1461-
None
1453+
let mut defid_to_rowid = |defid, check_external: bool| {
1454+
cache
1455+
.paths
1456+
.get(&defid)
1457+
.or_else(|| check_external.then(|| cache.external_paths.get(&defid)).flatten())
1458+
.map(|&(ref fqp, ty)| {
1459+
let pathid = serialized_index.names.len();
1460+
match serialized_index.crate_paths_index.entry((ty, fqp.clone())) {
1461+
Entry::Occupied(entry) => *entry.get(),
1462+
Entry::Vacant(entry) => {
1463+
entry.insert(pathid);
1464+
let (name, path) = fqp.split_last().unwrap();
1465+
serialized_index.push_path(
1466+
name.as_str().to_string(),
1467+
PathData {
1468+
ty,
1469+
module_path: path.to_vec(),
1470+
exact_module_path: if let Some(exact_path) =
1471+
cache.exact_paths.get(&defid)
1472+
&& let Some((name2, exact_path)) =
1473+
exact_path.split_last()
1474+
&& name == name2
1475+
{
1476+
Some(exact_path.to_vec())
1477+
} else {
1478+
None
1479+
},
14621480
},
1463-
},
1464-
);
1465-
usize::try_from(pathid).unwrap()
1481+
);
1482+
usize::try_from(pathid).unwrap()
1483+
}
14661484
}
1467-
}
1468-
})
1469-
});
1485+
})
1486+
};
1487+
item.parent_idx = item.parent.and_then(|p| defid_to_rowid(p, false));
1488+
item.trait_parent_idx = item.trait_parent.and_then(|p| defid_to_rowid(p, true));
14701489

14711490
if let Some(defid) = item.defid
14721491
&& item.parent_idx.is_none()
@@ -1549,6 +1568,7 @@ pub(crate) fn build_index(
15491568
EntryData {
15501569
ty: item.ty,
15511570
parent: item.parent_idx,
1571+
trait_parent: item.trait_parent_idx,
15521572
module_path,
15531573
exact_module_path,
15541574
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)