Skip to content

Commit

Permalink
Rollup merge of rust-lang#116597 - GuillaumeGomez:foreign-blanket-imp…
Browse files Browse the repository at this point in the history
…l, r=notriddle

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

Fixes rust-lang#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 ae15846 + 2d37b00 commit ab679de
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 ab679de

Please sign in to comment.