Skip to content

Commit 894caf8

Browse files
committed
rustdoc: Disambiguate anchors for assoc item impls
1 parent ed7c567 commit 894caf8

File tree

2 files changed

+53
-14
lines changed

2 files changed

+53
-14
lines changed

src/librustdoc/html/render.rs

+26-14
Original file line numberDiff line numberDiff line change
@@ -1903,34 +1903,35 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
19031903
if t.items.is_empty() {
19041904
write!(w, "{{ }}")?;
19051905
} else {
1906+
// FIXME: we should be using a derived_id for the Anchors here
19061907
write!(w, "{{\n")?;
19071908
for t in &types {
19081909
write!(w, " ")?;
1909-
render_assoc_item(w, t, AssocItemLink::Anchor)?;
1910+
render_assoc_item(w, t, AssocItemLink::Anchor(None))?;
19101911
write!(w, ";\n")?;
19111912
}
19121913
if !types.is_empty() && !consts.is_empty() {
19131914
w.write_str("\n")?;
19141915
}
19151916
for t in &consts {
19161917
write!(w, " ")?;
1917-
render_assoc_item(w, t, AssocItemLink::Anchor)?;
1918+
render_assoc_item(w, t, AssocItemLink::Anchor(None))?;
19181919
write!(w, ";\n")?;
19191920
}
19201921
if !consts.is_empty() && !required.is_empty() {
19211922
w.write_str("\n")?;
19221923
}
19231924
for m in &required {
19241925
write!(w, " ")?;
1925-
render_assoc_item(w, m, AssocItemLink::Anchor)?;
1926+
render_assoc_item(w, m, AssocItemLink::Anchor(None))?;
19261927
write!(w, ";\n")?;
19271928
}
19281929
if !required.is_empty() && !provided.is_empty() {
19291930
w.write_str("\n")?;
19301931
}
19311932
for m in &provided {
19321933
write!(w, " ")?;
1933-
render_assoc_item(w, m, AssocItemLink::Anchor)?;
1934+
render_assoc_item(w, m, AssocItemLink::Anchor(None))?;
19341935
write!(w, " {{ ... }}\n")?;
19351936
}
19361937
write!(w, "}}")?;
@@ -1947,7 +1948,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
19471948
write!(w, "<h3 id='{id}' class='method stab {stab}'><code>",
19481949
id = id,
19491950
stab = m.stability_class())?;
1950-
render_assoc_item(w, m, AssocItemLink::Anchor)?;
1951+
render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)))?;
19511952
write!(w, "</code>")?;
19521953
render_stability_since(w, m, t)?;
19531954
write!(w, "</h3>")?;
@@ -2042,7 +2043,8 @@ fn naive_assoc_href(it: &clean::Item, link: AssocItemLink) -> String {
20422043

20432044
let anchor = format!("#{}.{}", ty, name);
20442045
match link {
2045-
AssocItemLink::Anchor => anchor,
2046+
AssocItemLink::Anchor(Some(ref id)) => format!("#{}", id),
2047+
AssocItemLink::Anchor(None) => anchor,
20462048
AssocItemLink::GotoSource(did, _) => {
20472049
href(did).map(|p| format!("{}{}", p.0, anchor)).unwrap_or(anchor)
20482050
}
@@ -2117,7 +2119,8 @@ fn render_assoc_item(w: &mut fmt::Formatter,
21172119
let name = meth.name.as_ref().unwrap();
21182120
let anchor = format!("#{}.{}", shortty(meth), name);
21192121
let href = match link {
2120-
AssocItemLink::Anchor => anchor,
2122+
AssocItemLink::Anchor(Some(ref id)) => format!("#{}", id),
2123+
AssocItemLink::Anchor(None) => anchor,
21212124
AssocItemLink::GotoSource(did, provided_methods) => {
21222125
// We're creating a link from an impl-item to the corresponding
21232126
// trait-item and need to map the anchored type accordingly.
@@ -2378,10 +2381,19 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
23782381

23792382
#[derive(Copy, Clone)]
23802383
enum AssocItemLink<'a> {
2381-
Anchor,
2384+
Anchor(Option<&'a str>),
23822385
GotoSource(DefId, &'a HashSet<String>),
23832386
}
23842387

2388+
impl<'a> AssocItemLink<'a> {
2389+
fn anchor(&self, id: &'a String) -> Self {
2390+
match *self {
2391+
AssocItemLink::Anchor(_) => { AssocItemLink::Anchor(Some(&id)) },
2392+
ref other => *other,
2393+
}
2394+
}
2395+
}
2396+
23852397
enum AssocItemRender<'a> {
23862398
All,
23872399
DerefFor { trait_: &'a clean::Type, type_: &'a clean::Type },
@@ -2413,7 +2425,7 @@ fn render_assoc_items(w: &mut fmt::Formatter,
24132425
}
24142426
};
24152427
for i in &non_trait {
2416-
render_impl(w, cx, i, AssocItemLink::Anchor, render_header,
2428+
render_impl(w, cx, i, AssocItemLink::Anchor(None), render_header,
24172429
containing_item.stable_since())?;
24182430
}
24192431
}
@@ -2509,32 +2521,32 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
25092521
write!(w, "<h4 id='{}' class='{}'>", id, shortty)?;
25102522
render_stability_since_raw(w, item.stable_since(), outer_version)?;
25112523
write!(w, "<code>")?;
2512-
render_assoc_item(w, item, link)?;
2524+
render_assoc_item(w, item, link.anchor(&id))?;
25132525
write!(w, "</code></h4>\n")?;
25142526
}
25152527
}
25162528
clean::TypedefItem(ref tydef, _) => {
25172529
let id = derive_id(format!("{}.{}", ItemType::AssociatedType, name));
25182530
write!(w, "<h4 id='{}' class='{}'><code>", id, shortty)?;
2519-
assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link)?;
2531+
assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link.anchor(&id))?;
25202532
write!(w, "</code></h4>\n")?;
25212533
}
25222534
clean::AssociatedConstItem(ref ty, ref default) => {
25232535
let id = derive_id(format!("{}.{}", shortty, name));
25242536
write!(w, "<h4 id='{}' class='{}'><code>", id, shortty)?;
2525-
assoc_const(w, item, ty, default.as_ref(), link)?;
2537+
assoc_const(w, item, ty, default.as_ref(), link.anchor(&id))?;
25262538
write!(w, "</code></h4>\n")?;
25272539
}
25282540
clean::ConstantItem(ref c) => {
25292541
let id = derive_id(format!("{}.{}", shortty, name));
25302542
write!(w, "<h4 id='{}' class='{}'><code>", id, shortty)?;
2531-
assoc_const(w, item, &c.type_, Some(&c.expr), link)?;
2543+
assoc_const(w, item, &c.type_, Some(&c.expr), link.anchor(&id))?;
25322544
write!(w, "</code></h4>\n")?;
25332545
}
25342546
clean::AssociatedTypeItem(ref bounds, ref default) => {
25352547
let id = derive_id(format!("{}.{}", shortty, name));
25362548
write!(w, "<h4 id='{}' class='{}'><code>", id, shortty)?;
2537-
assoc_type(w, item, bounds, default.as_ref(), link)?;
2549+
assoc_type(w, item, bounds, default.as_ref(), link.anchor(&id))?;
25382550
write!(w, "</code></h4>\n")?;
25392551
}
25402552
clean::StrippedItem(..) => return Ok(()),

src/test/rustdoc/issue-32890.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// @has issue_32890/struct.Foo.html
12+
pub struct Foo<T>(T);
13+
14+
impl Foo<u8> {
15+
// @has - '//a[@href="#method.pass"]' 'pass'
16+
pub fn pass() {}
17+
}
18+
19+
impl Foo<u16> {
20+
// @has - '//a[@href="#method.pass-1"]' 'pass'
21+
pub fn pass() {}
22+
}
23+
24+
impl Foo<u32> {
25+
// @has - '//a[@href="#method.pass-2"]' 'pass'
26+
pub fn pass() {}
27+
}

0 commit comments

Comments
 (0)