mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-13 15:33:53 +00:00
Auto merge of #83068 - mockersf:method-trait-foreign-impl, r=GuillaumeGomez
rustdoc: links from items in a trait impl are inconsistent Depending on where the struct implementing a trait is coming from, or the current page, the items in a trait impl are not linking to the same thing: |item| trait page, implementors| trait page, implementations on Foreign Types|struct page, trait implementations| |-|-|-|-| |function| link to current impl|link to first impl in the list|link to trait def |default function | not present |not present |link to trait def |default function with custom impl|link to current impl|link to trait def |link to trait def |constant| link to current impl|link to trait def |link to trait def |associated type| link to current impl|link to trait def |link to trait def ||*missing link to trait def*|*function link wrong + missing link to current impl*|*missing link to current impl*| <details> <summary>rust code with those cases</summary> ```rust pub trait MyTrait { type Assoc; const VALUE: u32; fn trait_function(&self); fn defaulted(&self) {} fn defaulted_override(&self) {} } impl MyTrait for String { /// will link to trait def type Assoc = (); /// will link to trait def const VALUE: u32 = 5; /// will link to first foreign implementor fn trait_function(&self) {} /// will link to trait def fn defaulted_override(&self) {} } impl MyTrait for Vec<u8> { /// will link to trait def type Assoc = (); /// will link to trait def const VALUE: u32 = 5; /// will link to first foreign implementor fn trait_function(&self) {} /// will link to trait def fn defaulted_override(&self) {} } impl MyTrait for MyStruct { /// in trait page, will link to current impl /// /// in struct page, will link to trait def type Assoc = bool; /// in trait page, will link to current impl /// /// in struct page, will link to trait def const VALUE: u32 = 20; /// in trait page, will link to current impl /// /// in struct page, will link to trait def fn trait_function(&self) {} /// in trait page, will link to current impl /// /// in struct page, will link to trait def fn defaulted_override(&self) {} } pub struct MyStruct; ``` </details> In this PR, I fixed all links to target the trait definition, and added an anchor-link to the current implementation appearing on mouse hover.
This commit is contained in:
commit
b203b0d240
@ -912,10 +912,9 @@ fn render_assoc_item(
|
||||
let cache = cx.cache();
|
||||
let tcx = cx.tcx();
|
||||
let name = meth.name.as_ref().unwrap();
|
||||
let anchor = format!("#{}.{}", meth.type_(), name);
|
||||
let href = match link {
|
||||
AssocItemLink::Anchor(Some(ref id)) => format!("#{}", id),
|
||||
AssocItemLink::Anchor(None) => anchor,
|
||||
AssocItemLink::Anchor(None) => format!("#{}.{}", meth.type_(), name),
|
||||
AssocItemLink::GotoSource(did, provided_methods) => {
|
||||
// We're creating a link from an impl-item to the corresponding
|
||||
// trait-item and need to map the anchored type accordingly.
|
||||
@ -925,7 +924,9 @@ fn render_assoc_item(
|
||||
ItemType::TyMethod
|
||||
};
|
||||
|
||||
href(did, cache).map(|p| format!("{}#{}.{}", p.0, ty, name)).unwrap_or(anchor)
|
||||
href(did, cache)
|
||||
.map(|p| format!("{}#{}.{}", p.0, ty, name))
|
||||
.unwrap_or_else(|| format!("#{}.{}", ty, name))
|
||||
}
|
||||
};
|
||||
let vis = meth.visibility.print_with_space(tcx, meth.def_id, cache).to_string();
|
||||
@ -1452,14 +1453,32 @@ fn render_impl(
|
||||
} else {
|
||||
(true, " hidden")
|
||||
};
|
||||
let in_trait_class = if trait_.is_some() { " trait-impl" } else { "" };
|
||||
match *item.kind {
|
||||
clean::MethodItem(..) | clean::TyMethodItem(_) => {
|
||||
// Only render when the method is not static or we allow static methods
|
||||
if render_method_item {
|
||||
let id = cx.derive_id(format!("{}.{}", item_type, name));
|
||||
write!(w, "<h4 id=\"{}\" class=\"{}{}\">", id, item_type, extra_class);
|
||||
let source_id = trait_
|
||||
.and_then(|trait_| {
|
||||
trait_.items.iter().find(|item| {
|
||||
item.name.map(|n| n.as_str().eq(&name.as_str())).unwrap_or(false)
|
||||
})
|
||||
})
|
||||
.map(|item| format!("{}.{}", item.type_(), name));
|
||||
write!(
|
||||
w,
|
||||
"<h4 id=\"{}\" class=\"{}{}{}\">",
|
||||
id, item_type, extra_class, in_trait_class,
|
||||
);
|
||||
w.write_str("<code>");
|
||||
render_assoc_item(w, item, link.anchor(&id), ItemType::Impl, cx);
|
||||
render_assoc_item(
|
||||
w,
|
||||
item,
|
||||
link.anchor(source_id.as_ref().unwrap_or(&id)),
|
||||
ItemType::Impl,
|
||||
cx,
|
||||
);
|
||||
w.write_str("</code>");
|
||||
render_stability_since_raw(
|
||||
w,
|
||||
@ -1468,29 +1487,50 @@ fn render_impl(
|
||||
outer_version,
|
||||
outer_const_version,
|
||||
);
|
||||
write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
|
||||
write_srclink(cx, item, w);
|
||||
w.write_str("</h4>");
|
||||
}
|
||||
}
|
||||
clean::TypedefItem(ref tydef, _) => {
|
||||
let id = cx.derive_id(format!("{}.{}", ItemType::AssocType, name));
|
||||
write!(w, "<h4 id=\"{}\" class=\"{}{}\"><code>", id, item_type, extra_class);
|
||||
let source_id = format!("{}.{}", ItemType::AssocType, name);
|
||||
let id = cx.derive_id(source_id.clone());
|
||||
write!(
|
||||
w,
|
||||
"<h4 id=\"{}\" class=\"{}{}{}\"><code>",
|
||||
id, item_type, extra_class, in_trait_class
|
||||
);
|
||||
assoc_type(
|
||||
w,
|
||||
item,
|
||||
&Vec::new(),
|
||||
Some(&tydef.type_),
|
||||
link.anchor(&id),
|
||||
link.anchor(if trait_.is_some() { &source_id } else { &id }),
|
||||
"",
|
||||
cx.cache(),
|
||||
tcx,
|
||||
);
|
||||
w.write_str("</code></h4>");
|
||||
w.write_str("</code>");
|
||||
write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
|
||||
w.write_str("</h4>");
|
||||
}
|
||||
clean::AssocConstItem(ref ty, ref default) => {
|
||||
let id = cx.derive_id(format!("{}.{}", item_type, name));
|
||||
write!(w, "<h4 id=\"{}\" class=\"{}{}\"><code>", id, item_type, extra_class);
|
||||
assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), "", cx);
|
||||
let source_id = format!("{}.{}", item_type, name);
|
||||
let id = cx.derive_id(source_id.clone());
|
||||
write!(
|
||||
w,
|
||||
"<h4 id=\"{}\" class=\"{}{}{}\"><code>",
|
||||
id, item_type, extra_class, in_trait_class
|
||||
);
|
||||
assoc_const(
|
||||
w,
|
||||
item,
|
||||
ty,
|
||||
default.as_ref(),
|
||||
link.anchor(if trait_.is_some() { &source_id } else { &id }),
|
||||
"",
|
||||
cx,
|
||||
);
|
||||
w.write_str("</code>");
|
||||
render_stability_since_raw(
|
||||
w,
|
||||
@ -1499,23 +1539,31 @@ fn render_impl(
|
||||
outer_version,
|
||||
outer_const_version,
|
||||
);
|
||||
write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
|
||||
write_srclink(cx, item, w);
|
||||
w.write_str("</h4>");
|
||||
}
|
||||
clean::AssocTypeItem(ref bounds, ref default) => {
|
||||
let id = cx.derive_id(format!("{}.{}", item_type, name));
|
||||
write!(w, "<h4 id=\"{}\" class=\"{}{}\"><code>", id, item_type, extra_class);
|
||||
let source_id = format!("{}.{}", item_type, name);
|
||||
let id = cx.derive_id(source_id.clone());
|
||||
write!(
|
||||
w,
|
||||
"<h4 id=\"{}\" class=\"{}{}{}\"><code>",
|
||||
id, item_type, extra_class, in_trait_class
|
||||
);
|
||||
assoc_type(
|
||||
w,
|
||||
item,
|
||||
bounds,
|
||||
default.as_ref(),
|
||||
link.anchor(&id),
|
||||
link.anchor(if trait_.is_some() { &source_id } else { &id }),
|
||||
"",
|
||||
cx.cache(),
|
||||
tcx,
|
||||
);
|
||||
w.write_str("</code></h4>");
|
||||
w.write_str("</code>");
|
||||
write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
|
||||
w.write_str("</h4>");
|
||||
}
|
||||
clean::StrippedItem(..) => return,
|
||||
_ => panic!("can't make docs for trait item with name {:?}", item.name),
|
||||
@ -1605,7 +1653,7 @@ fn render_impl(
|
||||
true,
|
||||
outer_version,
|
||||
outer_const_version,
|
||||
None,
|
||||
Some(t),
|
||||
show_def_docs,
|
||||
);
|
||||
}
|
||||
|
@ -133,7 +133,8 @@ h3.impl, h3.method, h4.method, h3.type, h4.type, h4.associatedconstant {
|
||||
margin-bottom: 10px;
|
||||
position: relative;
|
||||
}
|
||||
h3.impl, h3.method, h3.type {
|
||||
h3.impl, h3.method, h4.method.trait-impl, h3.type,
|
||||
h4.type.trait-impl, h4.associatedconstant.trait-impl {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
@ -655,7 +656,8 @@ a {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
.in-band:hover > .anchor, .impl:hover > .anchor {
|
||||
.in-band:hover > .anchor, .impl:hover > .anchor, .method.trait-impl:hover > .anchor,
|
||||
.type.trait-impl:hover > .anchor, .associatedconstant.trait-impl:hover > .anchor {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
65
src/test/rustdoc/trait-impl-items-links-and-anchors.rs
Normal file
65
src/test/rustdoc/trait-impl-items-links-and-anchors.rs
Normal file
@ -0,0 +1,65 @@
|
||||
pub trait MyTrait {
|
||||
type Assoc;
|
||||
const VALUE: u32;
|
||||
fn trait_function(&self);
|
||||
fn defaulted(&self) {}
|
||||
fn defaulted_override(&self) {}
|
||||
}
|
||||
|
||||
|
||||
impl MyTrait for String {
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-1"]//a[@class="type"]/@href' #associatedtype.Assoc
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-1"]//a[@class="anchor"]/@href' #associatedtype.Assoc-1
|
||||
type Assoc = ();
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-1"]//a[@class="constant"]/@href' #associatedconstant.VALUE
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-1"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-1
|
||||
const VALUE: u32 = 5;
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function"]//a[@class="fnname"]/@href' #tymethod.trait_function
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function"]//a[@class="anchor"]/@href' #method.trait_function
|
||||
fn trait_function(&self) {}
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-1"]//a[@class="fnname"]/@href' #method.defaulted_override
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-1"]//a[@class="anchor"]/@href' #method.defaulted_override-1
|
||||
fn defaulted_override(&self) {}
|
||||
}
|
||||
|
||||
impl MyTrait for Vec<u8> {
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-2"]//a[@class="type"]/@href' #associatedtype.Assoc
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-2"]//a[@class="anchor"]/@href' #associatedtype.Assoc-2
|
||||
type Assoc = ();
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-2"]//a[@class="constant"]/@href' #associatedconstant.VALUE
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-2"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-2
|
||||
const VALUE: u32 = 5;
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function"]//a[@class="fnname"]/@href' #tymethod.trait_function
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function-1"]//a[@class="anchor"]/@href' #method.trait_function-1
|
||||
fn trait_function(&self) {}
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-2"]//a[@class="fnname"]/@href' #method.defaulted_override
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-2"]//a[@class="anchor"]/@href' #method.defaulted_override-2
|
||||
fn defaulted_override(&self) {}
|
||||
}
|
||||
|
||||
impl MyTrait for MyStruct {
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-3"]//a[@class="type"]/@href' #associatedtype.Assoc
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-3"]//a[@class="anchor"]/@href' #associatedtype.Assoc-3
|
||||
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedtype.Assoc"]//a[@class="type"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#associatedtype.Assoc
|
||||
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedtype.Assoc"]//a[@class="anchor"]/@href' #associatedtype.Assoc
|
||||
type Assoc = bool;
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-3"]//a[@class="constant"]/@href' #associatedconstant.VALUE
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-3"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-3
|
||||
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedconstant.VALUE"]//a[@class="constant"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#associatedconstant.VALUE
|
||||
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedconstant.VALUE"]//a[@class="anchor"]/@href' #associatedconstant.VALUE
|
||||
const VALUE: u32 = 20;
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function-2"]//a[@class="fnname"]/@href' #tymethod.trait_function
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function-2"]//a[@class="anchor"]/@href' #method.trait_function-2
|
||||
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.trait_function"]//a[@class="fnname"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#tymethod.trait_function
|
||||
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.trait_function"]//a[@class="anchor"]/@href' #method.trait_function
|
||||
fn trait_function(&self) {}
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-3"]//a[@class="fnname"]/@href' #method.defaulted_override
|
||||
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-3"]//a[@class="anchor"]/@href' #method.defaulted_override-3
|
||||
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted_override"]//a[@class="fnname"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#method.defaulted_override
|
||||
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted_override"]//a[@class="anchor"]/@href' #method.defaulted_override
|
||||
fn defaulted_override(&self) {}
|
||||
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted"]//a[@class="fnname"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#method.defaulted
|
||||
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted"]//a[@class="anchor"]/@href' #method.defaulted
|
||||
}
|
||||
|
||||
pub struct MyStruct;
|
Loading…
Reference in New Issue
Block a user