Skip to content

Commit e411480

Browse files
authored
Rollup merge of #149274 - GuillaumeGomez:tyalias-method-link, r=lolbinarycat
Fix invalid link generation for type alias methods Fixes #149205. That one was quite the wild ride. First commit is the actual fix, the second commit is just a small name variable improvement while I was going through the code. Anyway, let's go through it: * We don't generate directly implementations in the HTML files for local impls (which I think is a mistake and should be changed, gonna do that as a follow-up) but instead generate a JS file for each type alias containing the HTML for these impls. * So in `write_shared.rs::TypeAliasPart::get`, when generating the JS file, we generate the impl into a `String` by calling `render_impl`. This method expects an `AssocItemLink` to help it generate the correct link to the item (I'm planning to also remove this enum because it's yet another way to generate anchors/hrefs). * Problem was: we call the `provided_trait_methods` method on the impl item... which is empty if not a trait impl. This becomes an issue when we arrive in `render::assoc_href_attr` because of this code: ```rust AssocItemLink::GotoSource(did, provided_methods) => { let item_type = match item_type { ItemType::Method | ItemType::TyMethod => { if provided_methods.contains(&name) { ItemType::Method } else { ItemType::TyMethod } } item_type => item_type, }; // ... } ``` Since `provided_methods` is always empty, it means all methods on type aliases will be `TyMethod`, generating `#tymethod.` URLs instead of `#method.`. * So generating `AssocItemLink::GoToSource` only on traits (when `provided_trait_methods` is supposed to return something) was the fix. * And finally, because it's (currently) generating implementations only through JS, it means we cannot test it in `tests/rustdoc` so I had to write the test in `tests/rustdoc-gui`. Once I change how we generate local implementations for type aliases, I'll move it to `tests/rustdoc`. r? `@lolbinarycat`
2 parents bfbaac7 + 3181c21 commit e411480

File tree

4 files changed

+26
-15
lines changed

4 files changed

+26
-15
lines changed

src/librustdoc/html/render/mod.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2025,13 +2025,11 @@ fn render_impl(
20252025
let mut methods = Vec::new();
20262026

20272027
if !impl_.is_negative_trait_impl() {
2028-
for trait_item in &impl_.items {
2029-
match trait_item.kind {
2030-
clean::MethodItem(..) | clean::RequiredMethodItem(_) => {
2031-
methods.push(trait_item)
2032-
}
2028+
for impl_item in &impl_.items {
2029+
match impl_item.kind {
2030+
clean::MethodItem(..) | clean::RequiredMethodItem(_) => methods.push(impl_item),
20332031
clean::RequiredAssocTypeItem(..) | clean::AssocTypeItem(..) => {
2034-
assoc_types.push(trait_item)
2032+
assoc_types.push(impl_item)
20352033
}
20362034
clean::RequiredAssocConstItem(..)
20372035
| clean::ProvidedAssocConstItem(_)
@@ -2041,7 +2039,7 @@ fn render_impl(
20412039
&mut default_impl_items,
20422040
&mut impl_items,
20432041
cx,
2044-
trait_item,
2042+
impl_item,
20452043
if trait_.is_some() { &i.impl_item } else { parent },
20462044
link,
20472045
render_mode,

src/librustdoc/html/render/write_shared.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -568,18 +568,14 @@ impl TypeAliasPart {
568568
if let Some(ret) = &mut ret {
569569
ret.aliases.push(type_alias_fqp);
570570
} else {
571-
let target_did = impl_
572-
.inner_impl()
573-
.trait_
574-
.as_ref()
575-
.map(|trait_| trait_.def_id())
576-
.or_else(|| impl_.inner_impl().for_.def_id(&cx.shared.cache));
571+
let target_trait_did =
572+
impl_.inner_impl().trait_.as_ref().map(|trait_| trait_.def_id());
577573
let provided_methods;
578-
let assoc_link = if let Some(target_did) = target_did {
574+
let assoc_link = if let Some(target_trait_did) = target_trait_did {
579575
provided_methods =
580576
impl_.inner_impl().provided_trait_methods(cx.tcx());
581577
AssocItemLink::GotoSource(
582-
ItemId::DefId(target_did),
578+
ItemId::DefId(target_trait_did),
583579
&provided_methods,
584580
)
585581
} else {

tests/rustdoc-gui/src/test_docs/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,3 +786,13 @@ pub mod tooltips {
786786
Vec::new()
787787
}
788788
}
789+
790+
pub mod tyalias {
791+
pub struct X<T>(pub T);
792+
793+
impl<T: std::fmt::Debug> X<T> {
794+
pub fn blob(&self) {}
795+
}
796+
797+
pub type Y = X<u8>;
798+
}

tests/rustdoc-gui/type-alias.goml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// This test ensures that we correctly generate links to methods on type aliases.
2+
go-to: "file://" + |DOC_PATH| + "/test_docs/tyalias/type.Y.html"
3+
4+
// It's generated with JS so we need to wait for it to be done generating.
5+
wait-for: "#implementations"
6+
// We check that it's "#method." and not "#tymethod.".
7+
assert-text: ('#method\.blob a.fn[href="#method.blob"]', "blob")

0 commit comments

Comments
 (0)