diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index eebb07f0476..fc0ce4b1f09 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -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 { + 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!("
{}
", 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 { @@ -2328,19 +2344,8 @@ fn short_stability(item: &clean::Item, cx: &Context, parent: Option<&clean::Item stability.push(format!("
{}
", 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!("
{}
", cfg.render_long_html())); + if let Some(portability) = portability(item, parent) { + stability.push(portability); } stability @@ -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], @@ -2450,7 +2456,7 @@ fn render_implementor( w, cx, implementor, - None, + parent, AssocItemLink::Anchor(None), RenderMode::Normal, implementor.impl_item.stable_since().as_deref(), @@ -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(), @@ -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(), @@ -2749,7 +2755,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait, "
", ); 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, "
"); @@ -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()), @@ -3430,7 +3437,7 @@ fn render_assoc_items( w, cx, i, - Some(containing_item), + containing_item, AssocItemLink::Anchor(None), render_mode, containing_item.stable_since().as_deref(), @@ -3622,7 +3629,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>, @@ -3635,6 +3642,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) => { @@ -3687,6 +3697,13 @@ fn render_impl( ); } write!(w, ""); + + if trait_.is_some() { + if let Some(portability) = portability(&i.impl_item, Some(parent)) { + write!(w, "
{}
", portability); + } + } + if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) { let mut ids = cx.id_map.borrow_mut(); write!( @@ -3709,7 +3726,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, @@ -3794,7 +3811,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 { @@ -3804,13 +3821,13 @@ 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); } @@ -3818,16 +3835,13 @@ fn render_impl( } } - let traits = &cache.traits; - let trait_ = i.trait_did().map(|did| &traits[&did]); - write!(w, "
"); 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, @@ -3843,7 +3857,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, @@ -3884,7 +3898,7 @@ fn render_impl( cx, t, &i.inner_impl(), - parent, + &i.impl_item, render_mode, outer_version, show_def_docs, diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index cbf15cd0b6e..b8377dc1569 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -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) { @@ -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; } diff --git a/src/test/rustdoc/doc-cfg-traits.rs b/src/test/rustdoc/doc-cfg-traits.rs new file mode 100644 index 00000000000..13407b2c791 --- /dev/null +++ b/src/test/rustdoc/doc-cfg-traits.rs @@ -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 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 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 {}