Rollup merge of #97735 - jsha:no-foreign-std, r=GuillaumeGomez

Don't generate "Impls on Foreign Types" for std

Hack: many traits and types in std are re-exported from core or alloc. In general, rustdoc is capable of recognizing these implementations as being on local types. However, in at least one case, rustdoc gets confused and labels an implementation as being on a foreign type. To make sure that confusion doesn't pass on to the reader, consider all implementations in std, core, and alloc to be on local types.

Demo: https://rustdoc.crud.net/jsha/no-foreign-std/std/clone/trait.Clone.html
This commit is contained in:
Matthias Krüger 2022-06-04 23:42:03 +02:00 committed by GitHub
commit 8d0de3a8da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 18 additions and 6 deletions

View File

@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId;
pub(crate) use renderer::{run_format, FormatRenderer}; pub(crate) use renderer::{run_format, FormatRenderer};
use crate::clean::{self, ItemId}; use crate::clean::{self, ItemId};
use cache::Cache; use crate::html::render::Context;
/// Specifies whether rendering directly implemented trait items or ones from a certain Deref /// Specifies whether rendering directly implemented trait items or ones from a certain Deref
/// impl. /// impl.
@ -65,7 +65,8 @@ impl Impl {
// Returns true if this is an implementation on a "local" type, meaning: // Returns true if this is an implementation on a "local" type, meaning:
// the type is in the current crate, or the type and the trait are both // the type is in the current crate, or the type and the trait are both
// re-exported by the current crate. // re-exported by the current crate.
pub(crate) fn is_on_local_type(&self, cache: &Cache) -> bool { pub(crate) fn is_on_local_type(&self, cx: &Context<'_>) -> bool {
let cache = cx.cache();
let for_type = &self.inner_impl().for_; let for_type = &self.inner_impl().for_;
if let Some(for_type_did) = for_type.def_id(cache) { if let Some(for_type_did) = for_type.def_id(cache) {
// The "for" type is local if it's in the paths for the current crate. // The "for" type is local if it's in the paths for the current crate.
@ -80,6 +81,18 @@ impl Impl {
if for_type_did.krate == trait_did.krate { if for_type_did.krate == trait_did.krate {
return true; return true;
} }
// Hack: many traits and types in std are re-exported from
// core or alloc. In general, rustdoc is capable of recognizing
// these implementations as being on local types. However, in at
// least one case (https://github.com/rust-lang/rust/issues/97610),
// rustdoc gets confused and labels an implementation as being on
// a foreign type. To make sure that confusion doesn't pass on to
// the reader, consider all implementations in std, core, and alloc
// to be on local types.
let crate_name = cx.tcx().crate_name(trait_did.krate);
if matches!(crate_name.as_str(), "std" | "core" | "alloc") {
return true;
}
} }
return false; return false;
}; };

View File

@ -2281,11 +2281,10 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
|sym| format!("<a href=\"#{1}.{0}\">{0}</a>", sym, ItemType::Method), |sym| format!("<a href=\"#{1}.{0}\">{0}</a>", sym, ItemType::Method),
); );
let cache = cx.cache(); if let Some(implementors) = cx.cache().implementors.get(&it.item_id.expect_def_id()) {
if let Some(implementors) = cache.implementors.get(&it.item_id.expect_def_id()) {
let mut res = implementors let mut res = implementors
.iter() .iter()
.filter(|i| !i.is_on_local_type(cache)) .filter(|i| !i.is_on_local_type(cx))
.filter_map(|i| extract_for_impl_name(&i.impl_item, cx)) .filter_map(|i| extract_for_impl_name(&i.impl_item, cx))
.collect::<Vec<_>>(); .collect::<Vec<_>>();

View File

@ -823,7 +823,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
} }
let (local, foreign) = let (local, foreign) =
implementors.iter().partition::<Vec<_>, _>(|i| i.is_on_local_type(cache)); implementors.iter().partition::<Vec<_>, _>(|i| i.is_on_local_type(cx));
let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) = let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) =
local.iter().partition(|i| i.inner_impl().kind.is_auto()); local.iter().partition(|i| i.inner_impl().kind.is_auto());