Skip to content

Commit c34350a

Browse files
committed
Add tests and improve rendering of features on traits
1 parent 98d6634 commit c34350a

File tree

3 files changed

+174
-32
lines changed

3 files changed

+174
-32
lines changed

src/librustdoc/html/render/mod.rs

+43-29
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()),
@@ -3431,7 +3438,7 @@ fn render_assoc_items(
34313438
w,
34323439
cx,
34333440
i,
3434-
Some(containing_item),
3441+
containing_item,
34353442
AssocItemLink::Anchor(None),
34363443
render_mode,
34373444
containing_item.stable_since().as_deref(),
@@ -3623,7 +3630,7 @@ fn render_impl(
36233630
w: &mut Buffer,
36243631
cx: &Context,
36253632
i: &Impl,
3626-
parent: Option<&clean::Item>,
3633+
parent: &clean::Item,
36273634
link: AssocItemLink<'_>,
36283635
render_mode: RenderMode,
36293636
outer_version: Option<&str>,
@@ -3636,6 +3643,9 @@ fn render_impl(
36363643
aliases: &[String],
36373644
cache: &Cache,
36383645
) {
3646+
let traits = &cache.traits;
3647+
let trait_ = i.trait_did().map(|did| &traits[&did]);
3648+
36393649
if render_mode == RenderMode::Normal {
36403650
let id = cx.derive_id(match i.inner_impl().trait_ {
36413651
Some(ref t) => {
@@ -3688,6 +3698,13 @@ fn render_impl(
36883698
);
36893699
}
36903700
write!(w, "</h3>");
3701+
3702+
if trait_.is_some() {
3703+
if let Some(portability) = portability(&i.impl_item, Some(parent)) {
3704+
write!(w, "<div class=\"stability\">{}</div>", portability);
3705+
}
3706+
}
3707+
36913708
if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) {
36923709
let mut ids = cx.id_map.borrow_mut();
36933710
write!(
@@ -3710,7 +3727,7 @@ fn render_impl(
37103727
w: &mut Buffer,
37113728
cx: &Context,
37123729
item: &clean::Item,
3713-
parent: Option<&clean::Item>,
3730+
parent: &clean::Item,
37143731
link: AssocItemLink<'_>,
37153732
render_mode: RenderMode,
37163733
is_default_item: bool,
@@ -3795,7 +3812,7 @@ fn render_impl(
37953812
if let Some(it) = t.items.iter().find(|i| i.name == item.name) {
37963813
// We need the stability of the item from the trait
37973814
// because impls can't have a stability.
3798-
document_stability(w, cx, it, is_hidden, parent);
3815+
document_stability(w, cx, it, is_hidden, Some(parent));
37993816
if item.doc_value().is_some() {
38003817
document_full(w, item, cx, "", is_hidden);
38013818
} else if show_def_docs {
@@ -3805,30 +3822,27 @@ fn render_impl(
38053822
}
38063823
}
38073824
} else {
3808-
document_stability(w, cx, item, is_hidden, parent);
3825+
document_stability(w, cx, item, is_hidden, Some(parent));
38093826
if show_def_docs {
38103827
document_full(w, item, cx, "", is_hidden);
38113828
}
38123829
}
38133830
} else {
3814-
document_stability(w, cx, item, is_hidden, parent);
3831+
document_stability(w, cx, item, is_hidden, Some(parent));
38153832
if show_def_docs {
38163833
document_short(w, item, link, "", is_hidden);
38173834
}
38183835
}
38193836
}
38203837
}
38213838

3822-
let traits = &cache.traits;
3823-
let trait_ = i.trait_did().map(|did| &traits[&did]);
3824-
38253839
write!(w, "<div class=\"impl-items\">");
38263840
for trait_item in &i.inner_impl().items {
38273841
doc_impl_item(
38283842
w,
38293843
cx,
38303844
trait_item,
3831-
parent,
3845+
if trait_.is_some() { &i.impl_item } else { parent },
38323846
link,
38333847
render_mode,
38343848
false,
@@ -3844,7 +3858,7 @@ fn render_impl(
38443858
cx: &Context,
38453859
t: &clean::Trait,
38463860
i: &clean::Impl,
3847-
parent: Option<&clean::Item>,
3861+
parent: &clean::Item,
38483862
render_mode: RenderMode,
38493863
outer_version: Option<&str>,
38503864
show_def_docs: bool,
@@ -3885,7 +3899,7 @@ fn render_impl(
38853899
cx,
38863900
t,
38873901
&i.inner_impl(),
3888-
parent,
3902+
&i.impl_item,
38893903
render_mode,
38903904
outer_version,
38913905
show_def_docs,

src/librustdoc/html/static/main.js

+7-3
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

+124
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)