about summary refs log tree commit diff
diff options
context:
space:
mode:
-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());