Skip to content

Commit

Permalink
Rollup merge of #116597 - GuillaumeGomez:foreign-blanket-impl, r=notr…
Browse files Browse the repository at this point in the history
…iddle

Prevent showing methods from blanket impls of not available foreign traits to show up in the search results

Fixes #115480.

In the case that the blanket impl trait is not available in the current crate, we prevent adding its methods in the search index.

Now how I found how to fix the issue: the `equivalent` method is not generated in the documentation pages but was still added to the search index. To render impls, we iterate over `cache.impls` so I took a look at how this was generated. Inside `formats/cache.rs`, we have `CacheBuilder::populate` where we push impls into `impls` but with this condition:

```rust
if cx.cache.traits.contains_key(&trait_did) {
```

I re-used this condition in `CacheBuilder::fold_item` to prevent this method from being added in `cache.search_index` or `cache.orphan_impl_items`.

PS: If you want to double-check if the added test works, just comment the code I added in `cache.rs` and it should fail.

r? ``@notriddle``
  • Loading branch information
matthiaskrgr authored Oct 11, 2023
2 parents 3712ea8 + 2d37b00 commit d213983
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 2 deletions.
11 changes: 9 additions & 2 deletions src/librustdoc/formats/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,16 +221,23 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
_ => self.cache.stripped_mod,
};

#[inline]
fn is_from_private_dep(tcx: TyCtxt<'_>, cache: &Cache, def_id: DefId) -> bool {
let krate = def_id.krate;

cache.masked_crates.contains(&krate) || tcx.is_private_dep(krate)
}

// If the impl is from a masked crate or references something from a
// masked crate then remove it completely.
if let clean::ImplItem(ref i) = *item.kind &&
(self.cache.masked_crates.contains(&item.item_id.krate())
|| i.trait_
.as_ref()
.map_or(false, |t| self.cache.masked_crates.contains(&t.def_id().krate))
.map_or(false, |t| is_from_private_dep(self.tcx, self.cache, t.def_id()))
|| i.for_
.def_id(self.cache)
.map_or(false, |d| self.cache.masked_crates.contains(&d.krate)))
.map_or(false, |d| is_from_private_dep(self.tcx, self.cache, d)))
{
return None;
}
Expand Down
15 changes: 15 additions & 0 deletions tests/rustdoc-js/auxiliary/equivalent.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use std::borrow::Borrow;

pub trait Equivalent<K: ?Sized> {
fn equivalent(&self, key: &K) -> bool;
}

impl<Q: ?Sized, K: ?Sized> Equivalent<K> for Q
where
Q: Eq,
K: Borrow<Q>,
{
fn equivalent(&self, key: &K) -> bool {
PartialEq::eq(self, key.borrow())
}
}
9 changes: 9 additions & 0 deletions tests/rustdoc-js/search-non-local-trait-impl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// exact-check

// This test ensures that methods from blanket impls of not available foreign traits
// don't show up in the search results.

const EXPECTED = {
'query': 'equivalent',
'others': [],
};
8 changes: 8 additions & 0 deletions tests/rustdoc-js/search-non-local-trait-impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// aux-crate:priv:equivalent=equivalent.rs
// compile-flags: -Zunstable-options --extern equivalent
// edition:2018

extern crate equivalent;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct LayoutError;

0 comments on commit d213983

Please sign in to comment.