Skip to content

Commit 77ec591

Browse files
Rollup merge of rust-lang#98939 - GuillaumeGomez:rustdoc-disamb-impls, r=notriddle
rustdoc: Add more semantic information to impl IDs Take over of rust-lang#92745. I fixed the last remaining issue for the links in the sidebar (mentioned by `@jsha)` and fixed the few links broken in the std/core docs. cc `@camelid` r? `@notriddle`
2 parents d87bf24 + 53db831 commit 77ec591

29 files changed

+102
-113
lines changed

library/core/src/char/convert.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ impl const From<char> for u128 {
9393
/// Map `char` with code point in U+0000..=U+00FF to byte in 0x00..=0xFF with same value, failing
9494
/// if the code point is greater than U+00FF.
9595
///
96-
/// See [`impl From<u8> for char`](char#impl-From<u8>) for details on the encoding.
96+
/// See [`impl From<u8> for char`](char#impl-From<u8>-for-char) for details on the encoding.
9797
#[stable(feature = "u8_from_char", since = "1.59.0")]
9898
impl TryFrom<char> for u8 {
9999
type Error = TryFromCharError;
@@ -229,7 +229,7 @@ impl TryFrom<u32> for char {
229229

230230
/// The error type returned when a conversion from [`prim@u32`] to [`prim@char`] fails.
231231
///
232-
/// This `struct` is created by the [`char::try_from<u32>`](char#impl-TryFrom<u32>) method.
232+
/// This `struct` is created by the [`char::try_from<u32>`](char#impl-TryFrom<u32>-for-char) method.
233233
/// See its documentation for more.
234234
#[stable(feature = "try_from", since = "1.34.0")]
235235
#[derive(Copy, Clone, Debug, PartialEq, Eq)]

library/core/src/hash/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ mod sip;
180180
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
181181
/// [`HashSet`]: ../../std/collections/struct.HashSet.html
182182
/// [`hash`]: Hash::hash
183-
/// [impl]: ../../std/primitive.str.html#impl-Hash
183+
/// [impl]: ../../std/primitive.str.html#impl-Hash-for-str
184184
#[stable(feature = "rust1", since = "1.0.0")]
185185
#[rustc_diagnostic_item = "Hash"]
186186
pub trait Hash {

library/core/src/option.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@
389389
//! [`Option`] of a collection of each contained value of the original
390390
//! [`Option`] values, or [`None`] if any of the elements was [`None`].
391391
//!
392-
//! [impl-FromIterator]: Option#impl-FromIterator%3COption%3CA%3E%3E
392+
//! [impl-FromIterator]: Option#impl-FromIterator%3COption%3CA%3E%3E-for-Option%3CV%3E
393393
//!
394394
//! ```
395395
//! let v = [Some(2), Some(4), None, Some(8)];
@@ -405,8 +405,8 @@
405405
//! to provide the [`product`][Iterator::product] and
406406
//! [`sum`][Iterator::sum] methods.
407407
//!
408-
//! [impl-Product]: Option#impl-Product%3COption%3CU%3E%3E
409-
//! [impl-Sum]: Option#impl-Sum%3COption%3CU%3E%3E
408+
//! [impl-Product]: Option#impl-Product%3COption%3CU%3E%3E-for-Option%3CT%3E
409+
//! [impl-Sum]: Option#impl-Sum%3COption%3CU%3E%3E-for-Option%3CT%3E
410410
//!
411411
//! ```
412412
//! let v = [None, Some(1), Some(2), Some(3)];

library/core/src/result.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@
459459
//! [`Result`] of a collection of each contained value of the original
460460
//! [`Result`] values, or [`Err`] if any of the elements was [`Err`].
461461
//!
462-
//! [impl-FromIterator]: Result#impl-FromIterator%3CResult%3CA%2C%20E%3E%3E
462+
//! [impl-FromIterator]: Result#impl-FromIterator%3CResult%3CA%2C%20E%3E%3E-for-Result%3CV%2C%20E%3E
463463
//!
464464
//! ```
465465
//! let v = [Ok(2), Ok(4), Err("err!"), Ok(8)];
@@ -475,8 +475,8 @@
475475
//! to provide the [`product`][Iterator::product] and
476476
//! [`sum`][Iterator::sum] methods.
477477
//!
478-
//! [impl-Product]: Result#impl-Product%3CResult%3CU%2C%20E%3E%3E
479-
//! [impl-Sum]: Result#impl-Sum%3CResult%3CU%2C%20E%3E%3E
478+
//! [impl-Product]: Result#impl-Product%3CResult%3CU%2C%20E%3E%3E-for-Result%3CT%2C%20E%3E
479+
//! [impl-Sum]: Result#impl-Sum%3CResult%3CU%2C%20E%3E%3E-for-Result%3CT%2C%20E%3E
480480
//!
481481
//! ```
482482
//! let v = [Err("error!"), Ok(1), Ok(2), Ok(3), Err("foo")];

src/librustdoc/html/render/mod.rs

+20-40
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,6 @@ fn render_impls(
634634
&[],
635635
ImplRenderingParameters {
636636
show_def_docs: true,
637-
is_on_foreign_type: false,
638637
show_default_items: true,
639638
show_non_assoc_items: true,
640639
toggle_open_by_default,
@@ -1071,7 +1070,6 @@ fn render_assoc_items_inner(
10711070
&[],
10721071
ImplRenderingParameters {
10731072
show_def_docs: true,
1074-
is_on_foreign_type: false,
10751073
show_default_items: true,
10761074
show_non_assoc_items: true,
10771075
toggle_open_by_default: true,
@@ -1287,7 +1285,6 @@ fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String {
12871285
#[derive(Clone, Copy, Debug)]
12881286
struct ImplRenderingParameters {
12891287
show_def_docs: bool,
1290-
is_on_foreign_type: bool,
12911288
show_default_items: bool,
12921289
/// Whether or not to show methods.
12931290
show_non_assoc_items: bool,
@@ -1603,7 +1600,6 @@ fn render_impl(
16031600
parent,
16041601
rendering_params.show_def_docs,
16051602
use_absolute,
1606-
rendering_params.is_on_foreign_type,
16071603
aliases,
16081604
);
16091605
if toggled {
@@ -1688,21 +1684,12 @@ pub(crate) fn render_impl_summary(
16881684
containing_item: &clean::Item,
16891685
show_def_docs: bool,
16901686
use_absolute: Option<bool>,
1691-
is_on_foreign_type: bool,
16921687
// This argument is used to reference same type with different paths to avoid duplication
16931688
// in documentation pages for trait with automatic implementations like "Send" and "Sync".
16941689
aliases: &[String],
16951690
) {
1696-
let id = cx.derive_id(match i.inner_impl().trait_ {
1697-
Some(ref t) => {
1698-
if is_on_foreign_type {
1699-
get_id_for_impl_on_foreign_type(&i.inner_impl().for_, t, cx)
1700-
} else {
1701-
format!("impl-{}", small_url_encode(format!("{:#}", t.print(cx))))
1702-
}
1703-
}
1704-
None => "impl".to_string(),
1705-
});
1691+
let id =
1692+
cx.derive_id(get_id_for_impl(&i.inner_impl().for_, i.inner_impl().trait_.as_ref(), cx));
17061693
let aliases = if aliases.is_empty() {
17071694
String::new()
17081695
} else {
@@ -1986,21 +1973,18 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
19861973
let mut ret = impls
19871974
.iter()
19881975
.filter_map(|it| {
1989-
if let Some(ref i) = it.inner_impl().trait_ {
1990-
let i_display = format!("{:#}", i.print(cx));
1991-
let out = Escape(&i_display);
1992-
let encoded =
1993-
id_map.derive(small_url_encode(format!("impl-{:#}", i.print(cx))));
1994-
let prefix = match it.inner_impl().polarity {
1995-
ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
1996-
ty::ImplPolarity::Negative => "!",
1997-
};
1998-
let generated =
1999-
format!("<a href=\"#{}\">{}{}</a>", encoded, prefix, out);
2000-
if links.insert(generated.clone()) { Some(generated) } else { None }
2001-
} else {
2002-
None
2003-
}
1976+
let trait_ = it.inner_impl().trait_.as_ref()?;
1977+
let encoded =
1978+
id_map.derive(get_id_for_impl(&it.inner_impl().for_, Some(trait_), cx));
1979+
1980+
let i_display = format!("{:#}", trait_.print(cx));
1981+
let out = Escape(&i_display);
1982+
let prefix = match it.inner_impl().polarity {
1983+
ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
1984+
ty::ImplPolarity::Negative => "!",
1985+
};
1986+
let generated = format!("<a href=\"#{}\">{}{}</a>", encoded, prefix, out);
1987+
if links.insert(generated.clone()) { Some(generated) } else { None }
20041988
})
20051989
.collect::<Vec<String>>();
20061990
ret.sort();
@@ -2147,12 +2131,11 @@ fn sidebar_struct(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, s: &clea
21472131
}
21482132
}
21492133

2150-
fn get_id_for_impl_on_foreign_type(
2151-
for_: &clean::Type,
2152-
trait_: &clean::Path,
2153-
cx: &Context<'_>,
2154-
) -> String {
2155-
small_url_encode(format!("impl-{:#}-for-{:#}", trait_.print(cx), for_.print(cx)))
2134+
fn get_id_for_impl(for_: &clean::Type, trait_: Option<&clean::Path>, cx: &Context<'_>) -> String {
2135+
match trait_ {
2136+
Some(t) => small_url_encode(format!("impl-{:#}-for-{:#}", t.print(cx), for_.print(cx))),
2137+
None => small_url_encode(format!("impl-{:#}", for_.print(cx))),
2138+
}
21562139
}
21572140

21582141
fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String, String)> {
@@ -2161,10 +2144,7 @@ fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String
21612144
i.trait_.as_ref().map(|trait_| {
21622145
// Alternative format produces no URLs,
21632146
// so this parameter does nothing.
2164-
(
2165-
format!("{:#}", i.for_.print(cx)),
2166-
get_id_for_impl_on_foreign_type(&i.for_, trait_, cx),
2167-
)
2147+
(format!("{:#}", i.for_.print(cx)), get_id_for_impl(&i.for_, Some(trait_), cx))
21682148
})
21692149
}
21702150
_ => None,

src/librustdoc/html/render/print_item.rs

-2
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,6 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
864864
&[],
865865
ImplRenderingParameters {
866866
show_def_docs: false,
867-
is_on_foreign_type: true,
868867
show_default_items: false,
869868
show_non_assoc_items: true,
870869
toggle_open_by_default: false,
@@ -1642,7 +1641,6 @@ fn render_implementor(
16421641
aliases,
16431642
ImplRenderingParameters {
16441643
show_def_docs: false,
1645-
is_on_foreign_type: false,
16461644
show_default_items: false,
16471645
show_non_assoc_items: false,
16481646
toggle_open_by_default: false,

src/test/rustdoc-gui/anchors.goml

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ move-cursor-to: "h2#implementations"
2828
assert-css: ("h2#implementations a.anchor", {"color": "rgb(0, 0, 0)"})
2929

3030
// Same thing with the impl block title.
31-
move-cursor-to: "#impl"
32-
assert-css: ("#impl a.anchor", {"color": "rgb(0, 0, 0)"})
31+
move-cursor-to: "#impl-HeavilyDocumentedStruct"
32+
assert-css: ("#impl-HeavilyDocumentedStruct a.anchor", {"color": "rgb(0, 0, 0)"})
3333

3434
assert-css: ("#title-for-struct-impl-item-doc", {"margin-left": "0px"})

src/test/rustdoc-gui/headers-color.goml

+6-6
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ assert-css: (
2323
ALL,
2424
)
2525

26-
goto: file://|DOC_PATH|/test_docs/struct.Foo.html#impl
26+
goto: file://|DOC_PATH|/test_docs/struct.Foo.html#impl-Foo
2727
assert-css: (
28-
"#impl",
28+
"#impl-Foo",
2929
{"color": "rgb(197, 197, 197)", "background-color": "rgba(255, 236, 164, 0.06)"},
3030
)
3131

@@ -62,9 +62,9 @@ assert-css: (
6262
ALL,
6363
)
6464

65-
goto: file://|DOC_PATH|/test_docs/struct.Foo.html#impl
65+
goto: file://|DOC_PATH|/test_docs/struct.Foo.html#impl-Foo
6666
assert-css: (
67-
"#impl",
67+
"#impl-Foo",
6868
{"color": "rgb(221, 221, 221)", "background-color": "rgb(73, 74, 61)"},
6969
)
7070

@@ -99,8 +99,8 @@ assert-css: (
9999
ALL,
100100
)
101101

102-
goto: file://|DOC_PATH|/test_docs/struct.Foo.html#impl
103-
assert-css: ("#impl", {"color": "rgb(0, 0, 0)", "background-color": "rgb(253, 255, 211)"})
102+
goto: file://|DOC_PATH|/test_docs/struct.Foo.html#impl-Foo
103+
assert-css: ("#impl-Foo", {"color": "rgb(0, 0, 0)", "background-color": "rgb(253, 255, 211)"})
104104

105105
goto: file://|DOC_PATH|/test_docs/struct.Foo.html#method.must_use
106106
assert-css: (

src/test/rustdoc-gui/headings.goml

+6-6
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ assert-css: ("h4#sub-heading-for-field", {"border-bottom-width": "0px"})
3232
assert-css: ("h2#implementations", {"font-size": "22px"})
3333
assert-css: ("h2#implementations", {"border-bottom-width": "1px"})
3434

35-
assert-css: ("#impl > h3.code-header", {"font-size": "18px"})
36-
assert-css: ("#impl > h3.code-header", {"border-bottom-width": "0px"})
35+
assert-css: ("#impl-HeavilyDocumentedStruct > h3.code-header", {"font-size": "18px"})
36+
assert-css: ("#impl-HeavilyDocumentedStruct > h3.code-header", {"border-bottom-width": "0px"})
3737
assert-css: ("#method\.do_nothing > h4.code-header", {"font-size": "16px"})
3838
assert-css: ("#method\.do_nothing > h4.code-header", {"border-bottom-width": "0px"})
3939

@@ -87,8 +87,8 @@ assert-css: ("h6#structy-prose-sub-heading", {"border-bottom-width": "0px"})
8787
assert-css: ("h2#implementations", {"font-size": "22px"})
8888
assert-css: ("h2#implementations", {"border-bottom-width": "1px"})
8989

90-
assert-css: ("#impl > h3.code-header", {"font-size": "18px"})
91-
assert-css: ("#impl > h3.code-header", {"border-bottom-width": "0px"})
90+
assert-css: ("#impl-HeavilyDocumentedEnum > h3.code-header", {"font-size": "18px"})
91+
assert-css: ("#impl-HeavilyDocumentedEnum > h3.code-header", {"border-bottom-width": "0px"})
9292
assert-css: ("#method\.do_nothing > h4.code-header", {"font-size": "16px"})
9393
assert-css: ("#method\.do_nothing > h4.code-header", {"border-bottom-width": "0px"})
9494

@@ -129,8 +129,8 @@ assert-css: ("h4#sub-heading-for-union-variant", {"border-bottom-width": "0px"})
129129
assert-css: ("h2#implementations", {"font-size": "22px"})
130130
assert-css: ("h2#implementations", {"border-bottom-width": "1px"})
131131

132-
assert-css: ("#impl > h3.code-header", {"font-size": "18px"})
133-
assert-css: ("#impl > h3.code-header", {"border-bottom-width": "0px"})
132+
assert-css: ("#impl-HeavilyDocumentedUnion > h3.code-header", {"font-size": "18px"})
133+
assert-css: ("#impl-HeavilyDocumentedUnion > h3.code-header", {"border-bottom-width": "0px"})
134134
assert-css: ("h4#title-for-union-impl-doc", {"font-size": "16px"})
135135
assert-css: ("h4#title-for-union-impl-doc", {"border-bottom-width": "0px"})
136136
assert-css: ("h5#sub-heading-for-union-impl-doc", {"font-size": "16px"})

src/test/rustdoc-gui/implementors.goml

+12-4
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ assert: "#implementors-list"
66
assert-count: ("#implementors-list .impl", 2)
77
// Now we check that both implementors have an anchor, an ID and a similar DOM.
88
assert: ("#implementors-list .impl:nth-child(1) > a.anchor")
9-
assert-attribute: ("#implementors-list .impl:nth-child(1)", {"id": "impl-Whatever"})
10-
assert-attribute: ("#implementors-list .impl:nth-child(1) > a.anchor", {"href": "#impl-Whatever"})
9+
assert-attribute: ("#implementors-list .impl:nth-child(1)", {"id": "impl-Whatever-for-Struct"})
10+
assert-attribute: ("#implementors-list .impl:nth-child(1) > a.anchor", {"href": "#impl-Whatever-for-Struct"})
1111
assert: "#implementors-list .impl:nth-child(1) > .code-header.in-band"
1212

1313
assert: ("#implementors-list .impl:nth-child(2) > a.anchor")
@@ -16,8 +16,16 @@ assert-attribute: ("#implementors-list .impl:nth-child(2) > a.anchor", {"href":
1616
assert: "#implementors-list .impl:nth-child(2) > .code-header.in-band"
1717

1818
goto: file://|DOC_PATH|/test_docs/struct.HasEmptyTraits.html
19-
compare-elements-position-near-false: ("#impl-EmptyTrait1", "#impl-EmptyTrait2", {"y": 30})
20-
compare-elements-position-near: ("#impl-EmptyTrait3 h3", "#impl-EmptyTrait3 .item-info", {"y": 30})
19+
compare-elements-position-near-false: (
20+
"#impl-EmptyTrait1-for-HasEmptyTraits",
21+
"#impl-EmptyTrait2-for-HasEmptyTraits",
22+
{"y": 30},
23+
)
24+
compare-elements-position-near: (
25+
"#impl-EmptyTrait3-for-HasEmptyTraits h3",
26+
"#impl-EmptyTrait3-for-HasEmptyTraits .item-info",
27+
{"y": 30},
28+
)
2129

2230
// Now check that re-exports work correctly.
2331
// There should be exactly one impl shown on both of these pages.

src/test/rustdoc-gui/item-info-overflow.goml

+7-4
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,17 @@ assert-text: (
1515
// Checking the "item-info" on an impl block as well:
1616
goto: file://|DOC_PATH|/lib2/struct.LongItemInfo2.html
1717
compare-elements-property: (
18-
"#impl-SimpleTrait .item-info",
19-
"#impl-SimpleTrait + .docblock",
18+
"#impl-SimpleTrait-for-LongItemInfo2 .item-info",
19+
"#impl-SimpleTrait-for-LongItemInfo2 + .docblock",
2020
["scrollWidth"],
2121
)
22-
assert-property: ("#impl-SimpleTrait .item-info", {"scrollWidth": "866"})
22+
assert-property: (
23+
"#impl-SimpleTrait-for-LongItemInfo2 .item-info",
24+
{"scrollWidth": "866"},
25+
)
2326
// Just to be sure we're comparing the correct "item-info":
2427
assert-text: (
25-
"#impl-SimpleTrait .item-info",
28+
"#impl-SimpleTrait-for-LongItemInfo2 .item-info",
2629
"Available on Android or Linux or Emscripten or DragonFly BSD",
2730
STARTS_WITH,
2831
)

src/test/rustdoc-gui/toggle-click-deadspace.goml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ click: ".impl-items .rustdoc-toggle summary::before" // This is the position of
88
assert-attribute-false: (".impl-items .rustdoc-toggle", {"open": ""})
99

1010
// Click the "Trait" part of "impl Trait" and verify it navigates.
11-
click: "#impl-Trait h3 a:first-of-type"
11+
click: "#impl-Trait-for-Foo h3 a:first-of-type"
1212
assert-text: (".fqn .in-band", "Trait lib2::Trait")
+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#![crate_name = "foo"]
22

33
// @has 'foo/struct.Foo.html'
4-
// @has - '//*[@id="impl-Send"]' 'impl !Send for Foo'
5-
// @has - '//*[@id="impl-Sync"]' 'impl !Sync for Foo'
4+
// @has - '//*[@id="impl-Send-for-Foo"]' 'impl !Send for Foo'
5+
// @has - '//*[@id="impl-Sync-for-Foo"]' 'impl !Sync for Foo'
66
pub struct Foo(*const i8);
77
pub trait Whatever: Send {}
88
impl<T: Send + ?Sized> Whatever for T {}

src/test/rustdoc/blanket-reexport-item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![crate_name = "foo"]
22

3-
// @has foo/struct.S.html '//*[@id="impl-Into%3CU%3E"]//h3[@class="code-header in-band"]' 'impl<T, U> Into<U> for T'
3+
// @has foo/struct.S.html '//*[@id="impl-Into%3CU%3E-for-S"]//h3[@class="code-header in-band"]' 'impl<T, U> Into<U> for T'
44
pub struct S2 {}
55
mod m {
66
pub struct S {}

src/test/rustdoc/const-generics/const-generics-docs.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub struct Foo<const N: usize> where u8: Trait<N>;
3636
// @has foo/struct.Bar.html '//pre[@class="rust struct"]' 'pub struct Bar<T, const N: usize>(_)'
3737
pub struct Bar<T, const N: usize>([T; N]);
3838

39-
// @has foo/struct.Foo.html '//*[@id="impl"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Foo<M> where u8: Trait<M>'
39+
// @has foo/struct.Foo.html '//*[@id="impl-Foo%3CM%3E"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Foo<M> where u8: Trait<M>'
4040
impl<const M: usize> Foo<M> where u8: Trait<M> {
4141
// @has - '//*[@id="associatedconstant.FOO_ASSOC"]' 'pub const FOO_ASSOC: usize'
4242
pub const FOO_ASSOC: usize = M + 13;
@@ -47,7 +47,7 @@ impl<const M: usize> Foo<M> where u8: Trait<M> {
4747
}
4848
}
4949

50-
// @has foo/struct.Bar.html '//*[@id="impl"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Bar<u8, M>'
50+
// @has foo/struct.Bar.html '//*[@id="impl-Bar%3Cu8%2C%20M%3E"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Bar<u8, M>'
5151
impl<const M: usize> Bar<u8, M> {
5252
// @has - '//*[@id="method.hey"]' \
5353
// 'pub fn hey<const N: usize>(&self) -> Foo<N> where u8: Trait<N>'

0 commit comments

Comments
 (0)