Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests and improve rendering of cfgs on traits #78678

Merged
merged 1 commit into from
Nov 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 43 additions & 29 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2251,6 +2251,22 @@ fn stability_tags(item: &clean::Item, parent: &clean::Item) -> String {
tags
}

fn portability(item: &clean::Item, parent: Option<&clean::Item>) -> Option<String> {
let cfg = match (&item.attrs.cfg, parent.and_then(|p| p.attrs.cfg.as_ref())) {
(Some(cfg), Some(parent_cfg)) => cfg.simplify_with(parent_cfg),
(cfg, _) => cfg.as_deref().cloned(),
};

debug!(
"Portability {:?} - {:?} = {:?}",
item.attrs.cfg,
parent.and_then(|p| p.attrs.cfg.as_ref()),
cfg
);

Some(format!("<div class=\"stab portability\">{}</div>", cfg?.render_long_html()))
}

/// Render the stability and/or deprecation warning that is displayed at the top of the item's
/// documentation.
fn short_stability(item: &clean::Item, cx: &Context, parent: Option<&clean::Item>) -> Vec<String> {
Expand Down Expand Up @@ -2328,19 +2344,8 @@ fn short_stability(item: &clean::Item, cx: &Context, parent: Option<&clean::Item
stability.push(format!("<div class=\"stab unstable\">{}</div>", message));
}

let cfg = match (&item.attrs.cfg, parent.and_then(|p| p.attrs.cfg.as_ref())) {
(Some(cfg), Some(parent_cfg)) => cfg.simplify_with(parent_cfg),
(cfg, _) => cfg.as_deref().cloned(),
};

debug!(
"Portability {:?} - {:?} = {:?}",
item.attrs.cfg,
parent.and_then(|p| p.attrs.cfg.as_ref()),
cfg
);
if let Some(cfg) = cfg {
stability.push(format!("<div class=\"stab portability\">{}</div>", cfg.render_long_html()));
if let Some(portability) = portability(item, parent) {
stability.push(portability);
}

stability
Expand Down Expand Up @@ -2431,6 +2436,7 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
fn render_implementor(
cx: &Context,
implementor: &Impl,
parent: &clean::Item,
w: &mut Buffer,
implementor_dups: &FxHashMap<&str, (DefId, bool)>,
aliases: &[String],
Expand All @@ -2450,7 +2456,7 @@ fn render_implementor(
w,
cx,
implementor,
None,
parent,
AssocItemLink::Anchor(None),
RenderMode::Normal,
implementor.impl_item.stable_since().as_deref(),
Expand Down Expand Up @@ -2480,7 +2486,7 @@ fn render_impls(
&mut buffer,
cx,
i,
Some(containing_item),
containing_item,
assoc_link,
RenderMode::Normal,
containing_item.stable_since().as_deref(),
Expand Down Expand Up @@ -2727,7 +2733,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
w,
cx,
&implementor,
None,
it,
assoc_link,
RenderMode::Normal,
implementor.impl_item.stable_since().as_deref(),
Expand All @@ -2749,7 +2755,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
"<div class=\"item-list\" id=\"implementors-list\">",
);
for implementor in concrete {
render_implementor(cx, implementor, w, &implementor_dups, &[], cache);
render_implementor(cx, implementor, it, w, &implementor_dups, &[], cache);
}
write_loading_content(w, "</div>");

Expand All @@ -2764,6 +2770,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
render_implementor(
cx,
implementor,
it,
w,
&implementor_dups,
&collect_paths_for_type(implementor.inner_impl().for_.clone()),
Expand Down Expand Up @@ -3431,7 +3438,7 @@ fn render_assoc_items(
w,
cx,
i,
Some(containing_item),
containing_item,
AssocItemLink::Anchor(None),
render_mode,
containing_item.stable_since().as_deref(),
Expand Down Expand Up @@ -3623,7 +3630,7 @@ fn render_impl(
w: &mut Buffer,
cx: &Context,
i: &Impl,
parent: Option<&clean::Item>,
parent: &clean::Item,
link: AssocItemLink<'_>,
render_mode: RenderMode,
outer_version: Option<&str>,
Expand All @@ -3636,6 +3643,9 @@ fn render_impl(
aliases: &[String],
cache: &Cache,
) {
let traits = &cache.traits;
let trait_ = i.trait_did().map(|did| &traits[&did]);

if render_mode == RenderMode::Normal {
let id = cx.derive_id(match i.inner_impl().trait_ {
Some(ref t) => {
Expand Down Expand Up @@ -3688,6 +3698,13 @@ fn render_impl(
);
}
write!(w, "</h3>");

if trait_.is_some() {
if let Some(portability) = portability(&i.impl_item, Some(parent)) {
write!(w, "<div class=\"stability\">{}</div>", portability);
}
}

if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) {
let mut ids = cx.id_map.borrow_mut();
write!(
Expand All @@ -3710,7 +3727,7 @@ fn render_impl(
w: &mut Buffer,
cx: &Context,
item: &clean::Item,
parent: Option<&clean::Item>,
parent: &clean::Item,
link: AssocItemLink<'_>,
render_mode: RenderMode,
is_default_item: bool,
Expand Down Expand Up @@ -3795,7 +3812,7 @@ fn render_impl(
if let Some(it) = t.items.iter().find(|i| i.name == item.name) {
// We need the stability of the item from the trait
// because impls can't have a stability.
document_stability(w, cx, it, is_hidden, parent);
document_stability(w, cx, it, is_hidden, Some(parent));
if item.doc_value().is_some() {
document_full(w, item, cx, "", is_hidden);
} else if show_def_docs {
Expand All @@ -3805,30 +3822,27 @@ fn render_impl(
}
}
} else {
document_stability(w, cx, item, is_hidden, parent);
document_stability(w, cx, item, is_hidden, Some(parent));
if show_def_docs {
document_full(w, item, cx, "", is_hidden);
}
}
} else {
document_stability(w, cx, item, is_hidden, parent);
document_stability(w, cx, item, is_hidden, Some(parent));
if show_def_docs {
document_short(w, item, link, "", is_hidden);
}
}
}
}

let traits = &cache.traits;
let trait_ = i.trait_did().map(|did| &traits[&did]);

write!(w, "<div class=\"impl-items\">");
for trait_item in &i.inner_impl().items {
doc_impl_item(
w,
cx,
trait_item,
parent,
if trait_.is_some() { &i.impl_item } else { parent },
link,
render_mode,
false,
Expand All @@ -3844,7 +3858,7 @@ fn render_impl(
cx: &Context,
t: &clean::Trait,
i: &clean::Impl,
parent: Option<&clean::Item>,
parent: &clean::Item,
render_mode: RenderMode,
outer_version: Option<&str>,
show_def_docs: bool,
Expand Down Expand Up @@ -3885,7 +3899,7 @@ fn render_impl(
cx,
t,
&i.inner_impl(),
parent,
&i.impl_item,
render_mode,
outer_version,
show_def_docs,
Expand Down
10 changes: 7 additions & 3 deletions src/librustdoc/html/static/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2439,12 +2439,13 @@ function defocusSearchBar() {

var func = function(e) {
var next = e.nextElementSibling;
if (next && hasClass(next, "stability")) {
next = next.nextElementSibling;
}
if (!next) {
return;
}
if (hasClass(next, "docblock") === true ||
(hasClass(next, "stability") === true &&
hasClass(next.nextElementSibling, "docblock") === true)) {
if (hasClass(next, "docblock")) {
var newToggle = toggle.cloneNode(true);
insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]);
if (hideMethodDocs === true && hasClass(e, "method") === true) {
Expand All @@ -2455,6 +2456,9 @@ function defocusSearchBar() {

var funcImpl = function(e) {
var next = e.nextElementSibling;
if (next && hasClass(next, "stability")) {
next = next.nextElementSibling;
}
if (next && hasClass(next, "docblock")) {
next = next.nextElementSibling;
}
Expand Down
124 changes: 124 additions & 0 deletions src/test/rustdoc/doc-cfg-traits.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#![crate_name = "myrmecophagous"]
#![feature(doc_cfg, associated_type_defaults)]

// @has 'myrmecophagous/index.html'
// @count - '//*[@class="stab portability"]' 2
// @matches - '//*[@class="stab portability"]' '^jurisconsult$'
// @matches - '//*[@class="stab portability"]' '^quarter$'

pub trait Lea {}

// @has 'myrmecophagous/trait.Vortoscope.html'
// @count - '//*[@class="stab portability"]' 6
// @matches - '//*[@class="stab portability"]' 'crate feature zibib'
// @matches - '//*[@class="stab portability"]' 'crate feature poriform'
// @matches - '//*[@class="stab portability"]' 'crate feature ethopoeia'
// @matches - '//*[@class="stab portability"]' 'crate feature lea'
// @matches - '//*[@class="stab portability"]' 'crate feature unit'
// @matches - '//*[@class="stab portability"]' 'crate feature quarter'
pub trait Vortoscope {
type Batology = ();

#[doc(cfg(feature = "zibib"))]
type Zibib = ();

const YAHRZEIT: () = ();

#[doc(cfg(feature = "poriform"))]
const PORIFORM: () = ();

fn javanais() {}

#[doc(cfg(feature = "ethopoeia"))]
fn ethopoeia() {}
}

#[doc(cfg(feature = "lea"))]
impl<T: Lea> Vortoscope for T {}

#[doc(cfg(feature = "unit"))]
impl Vortoscope for () {}

// @has 'myrmecophagous/trait.Jurisconsult.html'
// @count - '//*[@class="stab portability"]' 7
// @matches - '//*[@class="stab portability"]' 'crate feature jurisconsult'
// @matches - '//*[@class="stab portability"]' 'crate feature lithomancy'
// @matches - '//*[@class="stab portability"]' 'crate feature boodle'
// @matches - '//*[@class="stab portability"]' 'crate feature mistetch'
// @matches - '//*[@class="stab portability"]' 'crate feature lea'
// @matches - '//*[@class="stab portability"]' 'crate feature unit'
// @matches - '//*[@class="stab portability"]' 'crate feature quarter'
#[doc(cfg(feature = "jurisconsult"))]
pub trait Jurisconsult {
type Urbanist = ();

#[doc(cfg(feature = "lithomancy"))]
type Lithomancy = ();

const UNIFILAR: () = ();

#[doc(cfg(feature = "boodle"))]
const BOODLE: () = ();

fn mersion() {}

#[doc(cfg(feature = "mistetch"))]
fn mistetch() {}
}

#[doc(cfg(feature = "lea"))]
impl<T: Lea> Jurisconsult for T {}

#[doc(cfg(feature = "unit"))]
impl Jurisconsult for () {}

// @has 'myrmecophagous/struct.Ultimogeniture.html'
// @count - '//*[@class="stab portability"]' 8
//
// @matches - '//*[@class="stab portability"]' 'crate feature zibib'
// @matches - '//*[@class="stab portability"]' 'crate feature poriform'
// @matches - '//*[@class="stab portability"]' 'crate feature ethopoeia'
//
// @matches - '//*[@class="stab portability"]' 'crate feature jurisconsult'
// @matches - '//*[@class="stab portability"]' 'crate feature lithomancy'
// @matches - '//*[@class="stab portability"]' 'crate feature boodle'
// @matches - '//*[@class="stab portability"]' 'crate feature mistetch'
//
// @matches - '//*[@class="stab portability"]' 'crate feature copy'
#[derive(Clone)]
pub struct Ultimogeniture;

impl Vortoscope for Ultimogeniture {}

#[doc(cfg(feature = "jurisconsult"))]
impl Jurisconsult for Ultimogeniture {}

#[doc(cfg(feature = "copy"))]
impl Copy for Ultimogeniture {}

// @has 'myrmecophagous/struct.Quarter.html'
// @count - '//*[@class="stab portability"]' 9
// @matches - '//*[@class="stab portability"]' 'crate feature quarter'
//
// @matches - '//*[@class="stab portability"]' 'crate feature zibib'
// @matches - '//*[@class="stab portability"]' 'crate feature poriform'
// @matches - '//*[@class="stab portability"]' 'crate feature ethopoeia'
//
// @matches - '//*[@class="stab portability"]' 'crate feature jurisconsult'
// @matches - '//*[@class="stab portability"]' 'crate feature lithomancy'
// @matches - '//*[@class="stab portability"]' 'crate feature boodle'
// @matches - '//*[@class="stab portability"]' 'crate feature mistetch'
//
// @matches - '//*[@class="stab portability"]' 'crate feature copy'
#[doc(cfg(feature = "quarter"))]
#[derive(Clone)]
pub struct Quarter;

#[doc(cfg(feature = "quarter"))]
impl Vortoscope for Quarter {}

#[doc(cfg(all(feature = "jurisconsult", feature = "quarter")))]
impl Jurisconsult for Quarter {}

#[doc(cfg(all(feature = "copy", feature = "quarter")))]
impl Copy for Quarter {}