about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJacob Hoffman-Andrews <github@hoffman-andrews.com>2022-06-04 11:03:45 -0700
committerJacob Hoffman-Andrews <github@hoffman-andrews.com>2022-06-04 11:10:51 -0700
commit784eebcc604a10c697f6dce2f82155268333c57c (patch)
tree8c8a8c30fe0754dcc3fdfdd4dae85fcdaf564bc9
parentc7b0452ece11bf714f7cf2003747231931504d59 (diff)
downloadrust-784eebcc604a10c697f6dce2f82155268333c57c.tar.gz
rust-784eebcc604a10c697f6dce2f82155268333c57c.zip
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.
-rw-r--r--src/librustdoc/formats/mod.rs17
-rw-r--r--src/librustdoc/html/render/mod.rs5
-rw-r--r--src/librustdoc/html/render/print_item.rs2
3 files changed, 18 insertions, 6 deletions
diff --git a/src/librustdoc/formats/mod.rs b/src/librustdoc/formats/mod.rs
index 9f26ccc74d1..b236bd7be4f 100644
--- a/src/librustdoc/formats/mod.rs
+++ b/src/librustdoc/formats/mod.rs
@@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId;
 pub(crate) use renderer::{run_format, FormatRenderer};
 
 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
 /// impl.
@@ -65,7 +65,8 @@ impl Impl {
     // 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
     // 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_;
         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.
@@ -80,6 +81,18 @@ impl Impl {
                 if for_type_did.krate == trait_did.krate {
                     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;
         };
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 0b801a20995..23ce634cf28 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -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),
     );
 
-    let cache = cx.cache();
-    if let Some(implementors) = cache.implementors.get(&it.item_id.expect_def_id()) {
+    if let Some(implementors) = cx.cache().implementors.get(&it.item_id.expect_def_id()) {
         let mut res = implementors
             .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))
             .collect::<Vec<_>>();
 
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 8683e6dfcd9..d115185562c 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -823,7 +823,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
         }
 
         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>) =
             local.iter().partition(|i| i.inner_impl().kind.is_auto());