Rollup merge of #116597 - GuillaumeGomez:foreign-blanket-impl, r=notriddle

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

Fixes https://github.com/rust-lang/rust/issues/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``
This commit is contained in:
Matthias Krüger 2023-10-11 20:08:22 +02:00 committed by GitHub
commit d2139834be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 2 deletions

View File

@ -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;
}

View File

@ -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())
}
}

View File

@ -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': [],
};

View File

@ -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;