Skip to content

Commit a96e71c

Browse files
authored
Rollup merge of rust-lang#97613 - jsha:implementation-is-on-local-type, r=GuillaumeGomez
rustdoc: Improve calculation of "Impls on Foreign Types" The existing code to calculate whether an implementation was on a "Foreign Type" was duplicated across the sidebar generation and the page generation. It also came to the wrong conclusion for some cases where both the trait and the "for" type were re-exports. This PR extracts the logic into a method of `Impl`, breaks it into a multi-line method so it can be commented, and adds a case for when the trait and the "for" type came from the same crate. This fixes some cases - like the platform-specific integer types (`__m256`, `__m128`, etc). But it doesn't fix all cases. See the screenshots below. [Before](https://doc.rust-lang.org/nightly/std/clone/trait.Clone.html#foreign-impls): <img src="https://user-images.githubusercontent.com/220205/171338226-59ce6daf-3d76-4bad-bc8d-72a8259a8f43.png" width=200> [After](https://rustdoc.crud.net/jsha/implementation-is-on-local-type/std/clone/trait.Clone.html): <img src="https://user-images.githubusercontent.com/220205/171338147-28308a65-1597-4223-be47-9550062404dd.png" width=200> The remaining types (`CString`, `NulError`, etc) are all from the `alloc` crate, while the `Clone` trait is from the `core` crate. Since `CString` and `Clone` are both re-exported by `std`, they are logically local to each other, but I couldn't figure out a good way to detect that in this code. I figure this is still a good step forward. Related: rust-lang#97610 r? `@camelid`
2 parents 2c1990d + 37d3638 commit a96e71c

File tree

4 files changed

+29
-7
lines changed

4 files changed

+29
-7
lines changed

src/librustdoc/formats/mod.rs

+25
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_hir::def_id::DefId;
77
pub(crate) use renderer::{run_format, FormatRenderer};
88

99
use crate::clean::{self, ItemId};
10+
use cache::Cache;
1011

1112
/// Specifies whether rendering directly implemented trait items or ones from a certain Deref
1213
/// impl.
@@ -60,4 +61,28 @@ impl Impl {
6061
}
6162
}
6263
}
64+
65+
// Returns true if this is an implementation on a "local" type, meaning:
66+
// the type is in the current crate, or the type and the trait are both
67+
// re-exported by the current crate.
68+
pub(crate) fn is_on_local_type(&self, cache: &Cache) -> bool {
69+
let for_type = &self.inner_impl().for_;
70+
if let Some(for_type_did) = for_type.def_id(cache) {
71+
// The "for" type is local if it's in the paths for the current crate.
72+
if cache.paths.contains_key(&for_type_did) {
73+
return true;
74+
}
75+
if let Some(trait_did) = self.trait_did() {
76+
// The "for" type and the trait are from the same crate. That could
77+
// be different from the current crate, for instance when both were
78+
// re-exported from some other crate. But they are local with respect to
79+
// each other.
80+
if for_type_did.krate == trait_did.krate {
81+
return true;
82+
}
83+
}
84+
return false;
85+
};
86+
true
87+
}
6388
}

src/librustdoc/html/render/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -2285,9 +2285,7 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
22852285
if let Some(implementors) = cache.implementors.get(&it.item_id.expect_def_id()) {
22862286
let mut res = implementors
22872287
.iter()
2288-
.filter(|i| {
2289-
i.inner_impl().for_.def_id(cache).map_or(false, |d| !cache.paths.contains_key(&d))
2290-
})
2288+
.filter(|i| !i.is_on_local_type(cache))
22912289
.filter_map(|i| extract_for_impl_name(&i.impl_item, cx))
22922290
.collect::<Vec<_>>();
22932291

src/librustdoc/html/render/print_item.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -822,9 +822,8 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
822822
}
823823
}
824824

825-
let (local, foreign) = implementors.iter().partition::<Vec<_>, _>(|i| {
826-
i.inner_impl().for_.def_id(cache).map_or(true, |d| cache.paths.contains_key(&d))
827-
});
825+
let (local, foreign) =
826+
implementors.iter().partition::<Vec<_>, _>(|i| i.is_on_local_type(cache));
828827

829828
let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) =
830829
local.iter().partition(|i| i.inner_impl().kind.is_auto());

src/test/rustdoc/issue-75588.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ extern crate real_gimli;
1313
// @!has foo/trait.Deref.html '//*[@id="impl-Deref-for-EndianSlice"]//h3[@class="code-header in-band"]' 'impl Deref for EndianSlice'
1414
pub use realcore::Deref;
1515

16-
// @has foo/trait.Join.html '//*[@id="impl-Join-for-Foo"]//h3[@class="code-header in-band"]' 'impl Join for Foo'
16+
// @has foo/trait.Join.html '//*[@id="impl-Join"]//h3[@class="code-header in-band"]' 'impl Join for Foo'
1717
pub use realcore::Join;

0 commit comments

Comments
 (0)