Skip to content

Commit f0965d5

Browse files
Rollup merge of #78678 - Nemo157:doc-cfg-w-traits, r=jyn514,GuillaumeGomez
Add tests and improve rendering of cfgs on traits Shows the additional features required to get the trait implementation, suppressing any already shown on the current page. One interesting effect from this is if you have a cfg-ed type, implementing a cfg-ed trait (so the implementation depends on both cfgs), you will get the inverted pair of cfgs shown on each page: ![image](https://user-images.githubusercontent.com/81079/97904671-207bdc00-1d41-11eb-8144-707e8017d2b6.png) ![image](https://user-images.githubusercontent.com/81079/97904700-27a2ea00-1d41-11eb-8b9f-e925ba339044.png) The hidden items on the trait implementation also now get the correct cfgs displayed on them. Tests are blocked on #78673. fixes #68100 cc #43781
2 parents a3eaa85 + c34350a commit f0965d5

File tree

3 files changed

+174
-32
lines changed

3 files changed

+174
-32
lines changed

src/librustdoc/html/render/mod.rs

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2251,6 +2251,22 @@ fn stability_tags(item: &clean::Item, parent: &clean::Item) -> String {
22512251
tags
22522252
}
22532253

2254+
fn portability(item: &clean::Item, parent: Option<&clean::Item>) -> Option<String> {
2255+
let cfg = match (&item.attrs.cfg, parent.and_then(|p| p.attrs.cfg.as_ref())) {
2256+
(Some(cfg), Some(parent_cfg)) => cfg.simplify_with(parent_cfg),
2257+
(cfg, _) => cfg.as_deref().cloned(),
2258+
};
2259+
2260+
debug!(
2261+
"Portability {:?} - {:?} = {:?}",
2262+
item.attrs.cfg,
2263+
parent.and_then(|p| p.attrs.cfg.as_ref()),
2264+
cfg
2265+
);
2266+
2267+
Some(format!("<div class=\"stab portability\">{}</div>", cfg?.render_long_html()))
2268+
}
2269+
22542270
/// Render the stability and/or deprecation warning that is displayed at the top of the item's
22552271
/// documentation.
22562272
fn short_stability(item: &clean::Item, cx: &Context, parent: Option<&clean::Item>) -> Vec<String> {
@@ -2328,19 +2344,8 @@ fn short_stability(item: &clean::Item, cx: &Context, parent: Option<&clean::Item
23282344
stability.push(format!("<div class=\"stab unstable\">{}</div>", message));
23292345
}
23302346

2331-
let cfg = match (&item.attrs.cfg, parent.and_then(|p| p.attrs.cfg.as_ref())) {
2332-
(Some(cfg), Some(parent_cfg)) => cfg.simplify_with(parent_cfg),
2333-
(cfg, _) => cfg.as_deref().cloned(),
2334-
};
2335-
2336-
debug!(
2337-
"Portability {:?} - {:?} = {:?}",
2338-
item.attrs.cfg,
2339-
parent.and_then(|p| p.attrs.cfg.as_ref()),
2340-
cfg
2341-
);
2342-
if let Some(cfg) = cfg {
2343-
stability.push(format!("<div class=\"stab portability\">{}</div>", cfg.render_long_html()));
2347+
if let Some(portability) = portability(item, parent) {
2348+
stability.push(portability);
23442349
}
23452350

23462351
stability
@@ -2431,6 +2436,7 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
24312436
fn render_implementor(
24322437
cx: &Context,
24332438
implementor: &Impl,
2439+
parent: &clean::Item,
24342440
w: &mut Buffer,
24352441
implementor_dups: &FxHashMap<&str, (DefId, bool)>,
24362442
aliases: &[String],
@@ -2450,7 +2456,7 @@ fn render_implementor(
24502456
w,
24512457
cx,
24522458
implementor,
2453-
None,
2459+
parent,
24542460
AssocItemLink::Anchor(None),
24552461
RenderMode::Normal,
24562462
implementor.impl_item.stable_since().as_deref(),
@@ -2480,7 +2486,7 @@ fn render_impls(
24802486
&mut buffer,
24812487
cx,
24822488
i,
2483-
Some(containing_item),
2489+
containing_item,
24842490
assoc_link,
24852491
RenderMode::Normal,
24862492
containing_item.stable_since().as_deref(),
@@ -2727,7 +2733,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
27272733
w,
27282734
cx,
27292735
&implementor,
2730-
None,
2736+
it,
27312737
assoc_link,
27322738
RenderMode::Normal,
27332739
implementor.impl_item.stable_since().as_deref(),
@@ -2749,7 +2755,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
27492755
"<div class=\"item-list\" id=\"implementors-list\">",
27502756
);
27512757
for implementor in concrete {
2752-
render_implementor(cx, implementor, w, &implementor_dups, &[], cache);
2758+
render_implementor(cx, implementor, it, w, &implementor_dups, &[], cache);
27532759
}
27542760
write_loading_content(w, "</div>");
27552761

@@ -2764,6 +2770,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
27642770
render_implementor(
27652771
cx,
27662772
implementor,
2773+
it,
27672774
w,
27682775
&implementor_dups,
27692776
&collect_paths_for_type(implementor.inner_impl().for_.clone()),
@@ -3430,7 +3437,7 @@ fn render_assoc_items(
34303437
w,
34313438
cx,
34323439
i,
3433-
Some(containing_item),
3440+
containing_item,
34343441
AssocItemLink::Anchor(None),
34353442
render_mode,
34363443
containing_item.stable_since().as_deref(),
@@ -3622,7 +3629,7 @@ fn render_impl(
36223629
w: &mut Buffer,
36233630
cx: &Context,
36243631
i: &Impl,
3625-
parent: Option<&clean::Item>,
3632+
parent: &clean::Item,
36263633
link: AssocItemLink<'_>,
36273634
render_mode: RenderMode,
36283635
outer_version: Option<&str>,
@@ -3635,6 +3642,9 @@ fn render_impl(
36353642
aliases: &[String],
36363643
cache: &Cache,
36373644
) {
3645+
let traits = &cache.traits;
3646+
let trait_ = i.trait_did().map(|did| &traits[&did]);
3647+
36383648
if render_mode == RenderMode::Normal {
36393649
let id = cx.derive_id(match i.inner_impl().trait_ {
36403650
Some(ref t) => {
@@ -3687,6 +3697,13 @@ fn render_impl(
36873697
);
36883698
}
36893699
write!(w, "</h3>");
3700+
3701+
if trait_.is_some() {
3702+
if let Some(portability) = portability(&i.impl_item, Some(parent)) {
3703+
write!(w, "<div class=\"stability\">{}</div>", portability);
3704+
}
3705+
}
3706+
36903707
if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) {
36913708
let mut ids = cx.id_map.borrow_mut();
36923709
write!(
@@ -3709,7 +3726,7 @@ fn render_impl(
37093726
w: &mut Buffer,
37103727
cx: &Context,
37113728
item: &clean::Item,
3712-
parent: Option<&clean::Item>,
3729+
parent: &clean::Item,
37133730
link: AssocItemLink<'_>,
37143731
render_mode: RenderMode,
37153732
is_default_item: bool,
@@ -3794,7 +3811,7 @@ fn render_impl(
37943811
if let Some(it) = t.items.iter().find(|i| i.name == item.name) {
37953812
// We need the stability of the item from the trait
37963813
// because impls can't have a stability.
3797-
document_stability(w, cx, it, is_hidden, parent);
3814+
document_stability(w, cx, it, is_hidden, Some(parent));
37983815
if item.doc_value().is_some() {
37993816
document_full(w, item, cx, "", is_hidden);
38003817
} else if show_def_docs {
@@ -3804,30 +3821,27 @@ fn render_impl(
38043821
}
38053822
}
38063823
} else {
3807-
document_stability(w, cx, item, is_hidden, parent);
3824+
document_stability(w, cx, item, is_hidden, Some(parent));
38083825
if show_def_docs {
38093826
document_full(w, item, cx, "", is_hidden);
38103827
}
38113828
}
38123829
} else {
3813-
document_stability(w, cx, item, is_hidden, parent);
3830+
document_stability(w, cx, item, is_hidden, Some(parent));
38143831
if show_def_docs {
38153832
document_short(w, item, link, "", is_hidden);
38163833
}
38173834
}
38183835
}
38193836
}
38203837

3821-
let traits = &cache.traits;
3822-
let trait_ = i.trait_did().map(|did| &traits[&did]);
3823-
38243838
write!(w, "<div class=\"impl-items\">");
38253839
for trait_item in &i.inner_impl().items {
38263840
doc_impl_item(
38273841
w,
38283842
cx,
38293843
trait_item,
3830-
parent,
3844+
if trait_.is_some() { &i.impl_item } else { parent },
38313845
link,
38323846
render_mode,
38333847
false,
@@ -3843,7 +3857,7 @@ fn render_impl(
38433857
cx: &Context,
38443858
t: &clean::Trait,
38453859
i: &clean::Impl,
3846-
parent: Option<&clean::Item>,
3860+
parent: &clean::Item,
38473861
render_mode: RenderMode,
38483862
outer_version: Option<&str>,
38493863
show_def_docs: bool,
@@ -3884,7 +3898,7 @@ fn render_impl(
38843898
cx,
38853899
t,
38863900
&i.inner_impl(),
3887-
parent,
3901+
&i.impl_item,
38883902
render_mode,
38893903
outer_version,
38903904
show_def_docs,

src/librustdoc/html/static/main.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2439,12 +2439,13 @@ function defocusSearchBar() {
24392439

24402440
var func = function(e) {
24412441
var next = e.nextElementSibling;
2442+
if (next && hasClass(next, "stability")) {
2443+
next = next.nextElementSibling;
2444+
}
24422445
if (!next) {
24432446
return;
24442447
}
2445-
if (hasClass(next, "docblock") === true ||
2446-
(hasClass(next, "stability") === true &&
2447-
hasClass(next.nextElementSibling, "docblock") === true)) {
2448+
if (hasClass(next, "docblock")) {
24482449
var newToggle = toggle.cloneNode(true);
24492450
insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]);
24502451
if (hideMethodDocs === true && hasClass(e, "method") === true) {
@@ -2455,6 +2456,9 @@ function defocusSearchBar() {
24552456

24562457
var funcImpl = function(e) {
24572458
var next = e.nextElementSibling;
2459+
if (next && hasClass(next, "stability")) {
2460+
next = next.nextElementSibling;
2461+
}
24582462
if (next && hasClass(next, "docblock")) {
24592463
next = next.nextElementSibling;
24602464
}

src/test/rustdoc/doc-cfg-traits.rs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#![crate_name = "myrmecophagous"]
2+
#![feature(doc_cfg, associated_type_defaults)]
3+
4+
// @has 'myrmecophagous/index.html'
5+
// @count - '//*[@class="stab portability"]' 2
6+
// @matches - '//*[@class="stab portability"]' '^jurisconsult$'
7+
// @matches - '//*[@class="stab portability"]' '^quarter$'
8+
9+
pub trait Lea {}
10+
11+
// @has 'myrmecophagous/trait.Vortoscope.html'
12+
// @count - '//*[@class="stab portability"]' 6
13+
// @matches - '//*[@class="stab portability"]' 'crate feature zibib'
14+
// @matches - '//*[@class="stab portability"]' 'crate feature poriform'
15+
// @matches - '//*[@class="stab portability"]' 'crate feature ethopoeia'
16+
// @matches - '//*[@class="stab portability"]' 'crate feature lea'
17+
// @matches - '//*[@class="stab portability"]' 'crate feature unit'
18+
// @matches - '//*[@class="stab portability"]' 'crate feature quarter'
19+
pub trait Vortoscope {
20+
type Batology = ();
21+
22+
#[doc(cfg(feature = "zibib"))]
23+
type Zibib = ();
24+
25+
const YAHRZEIT: () = ();
26+
27+
#[doc(cfg(feature = "poriform"))]
28+
const PORIFORM: () = ();
29+
30+
fn javanais() {}
31+
32+
#[doc(cfg(feature = "ethopoeia"))]
33+
fn ethopoeia() {}
34+
}
35+
36+
#[doc(cfg(feature = "lea"))]
37+
impl<T: Lea> Vortoscope for T {}
38+
39+
#[doc(cfg(feature = "unit"))]
40+
impl Vortoscope for () {}
41+
42+
// @has 'myrmecophagous/trait.Jurisconsult.html'
43+
// @count - '//*[@class="stab portability"]' 7
44+
// @matches - '//*[@class="stab portability"]' 'crate feature jurisconsult'
45+
// @matches - '//*[@class="stab portability"]' 'crate feature lithomancy'
46+
// @matches - '//*[@class="stab portability"]' 'crate feature boodle'
47+
// @matches - '//*[@class="stab portability"]' 'crate feature mistetch'
48+
// @matches - '//*[@class="stab portability"]' 'crate feature lea'
49+
// @matches - '//*[@class="stab portability"]' 'crate feature unit'
50+
// @matches - '//*[@class="stab portability"]' 'crate feature quarter'
51+
#[doc(cfg(feature = "jurisconsult"))]
52+
pub trait Jurisconsult {
53+
type Urbanist = ();
54+
55+
#[doc(cfg(feature = "lithomancy"))]
56+
type Lithomancy = ();
57+
58+
const UNIFILAR: () = ();
59+
60+
#[doc(cfg(feature = "boodle"))]
61+
const BOODLE: () = ();
62+
63+
fn mersion() {}
64+
65+
#[doc(cfg(feature = "mistetch"))]
66+
fn mistetch() {}
67+
}
68+
69+
#[doc(cfg(feature = "lea"))]
70+
impl<T: Lea> Jurisconsult for T {}
71+
72+
#[doc(cfg(feature = "unit"))]
73+
impl Jurisconsult for () {}
74+
75+
// @has 'myrmecophagous/struct.Ultimogeniture.html'
76+
// @count - '//*[@class="stab portability"]' 8
77+
//
78+
// @matches - '//*[@class="stab portability"]' 'crate feature zibib'
79+
// @matches - '//*[@class="stab portability"]' 'crate feature poriform'
80+
// @matches - '//*[@class="stab portability"]' 'crate feature ethopoeia'
81+
//
82+
// @matches - '//*[@class="stab portability"]' 'crate feature jurisconsult'
83+
// @matches - '//*[@class="stab portability"]' 'crate feature lithomancy'
84+
// @matches - '//*[@class="stab portability"]' 'crate feature boodle'
85+
// @matches - '//*[@class="stab portability"]' 'crate feature mistetch'
86+
//
87+
// @matches - '//*[@class="stab portability"]' 'crate feature copy'
88+
#[derive(Clone)]
89+
pub struct Ultimogeniture;
90+
91+
impl Vortoscope for Ultimogeniture {}
92+
93+
#[doc(cfg(feature = "jurisconsult"))]
94+
impl Jurisconsult for Ultimogeniture {}
95+
96+
#[doc(cfg(feature = "copy"))]
97+
impl Copy for Ultimogeniture {}
98+
99+
// @has 'myrmecophagous/struct.Quarter.html'
100+
// @count - '//*[@class="stab portability"]' 9
101+
// @matches - '//*[@class="stab portability"]' 'crate feature quarter'
102+
//
103+
// @matches - '//*[@class="stab portability"]' 'crate feature zibib'
104+
// @matches - '//*[@class="stab portability"]' 'crate feature poriform'
105+
// @matches - '//*[@class="stab portability"]' 'crate feature ethopoeia'
106+
//
107+
// @matches - '//*[@class="stab portability"]' 'crate feature jurisconsult'
108+
// @matches - '//*[@class="stab portability"]' 'crate feature lithomancy'
109+
// @matches - '//*[@class="stab portability"]' 'crate feature boodle'
110+
// @matches - '//*[@class="stab portability"]' 'crate feature mistetch'
111+
//
112+
// @matches - '//*[@class="stab portability"]' 'crate feature copy'
113+
#[doc(cfg(feature = "quarter"))]
114+
#[derive(Clone)]
115+
pub struct Quarter;
116+
117+
#[doc(cfg(feature = "quarter"))]
118+
impl Vortoscope for Quarter {}
119+
120+
#[doc(cfg(all(feature = "jurisconsult", feature = "quarter")))]
121+
impl Jurisconsult for Quarter {}
122+
123+
#[doc(cfg(all(feature = "copy", feature = "quarter")))]
124+
impl Copy for Quarter {}

0 commit comments

Comments
 (0)