From 4488f9bc0fa8661b7109d7ce94a275846222c816 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Fri, 23 Jun 2017 18:39:27 +0100 Subject: [PATCH] rustdoc: Fix a few issues with associated consts * Make sure private consts are stripped. * Don't show a code block for the value if there is none. * Make sure default values are shown in impls. * Make sure docs from the trait are used if the impl has no docs. --- src/librustdoc/html/render.rs | 66 +++++++++++--------------- src/librustdoc/passes/mod.rs | 6 +-- src/test/rustdoc/assoc-consts.rs | 79 ++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 43 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 0299e45599b..db1bb28c890 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1628,12 +1628,13 @@ fn plain_summary_line(s: Option<&str>) -> String { fn document(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item) -> fmt::Result { document_stability(w, cx, item)?; - document_full(w, item, cx.render_type)?; + let prefix = render_assoc_const_value(item); + document_full(w, item, cx.render_type, &prefix)?; Ok(()) } fn document_short(w: &mut fmt::Formatter, item: &clean::Item, link: AssocItemLink, - render_type: RenderType) -> fmt::Result { + render_type: RenderType, prefix: &str) -> fmt::Result { if let Some(s) = item.doc_value() { let markdown = if s.contains('\n') { format!("{} [Read more]({})", @@ -1641,42 +1642,33 @@ fn document_short(w: &mut fmt::Formatter, item: &clean::Item, link: AssocItemLin } else { format!("{}", &plain_summary_line(Some(s))) }; - write!(w, "
{}
", - Markdown(&markdown, render_type))?; + write!(w, "
{}{}
", prefix, Markdown(&markdown, render_type))?; + } else if !prefix.is_empty() { + write!(w, "
{}
", prefix)?; } Ok(()) } -fn md_render_assoc_item(item: &clean::Item) -> String { +fn render_assoc_const_value(item: &clean::Item) -> String { match item.inner { - clean::AssociatedConstItem(ref ty, ref default) => { - if let Some(default) = default.as_ref() { - format!("```\n{}: {:#} = {}\n```\n\n", item.name.as_ref().unwrap(), ty, default) - } else { - format!("```\n{}: {:#}\n```\n\n", item.name.as_ref().unwrap(), ty) - } + clean::AssociatedConstItem(ref ty, Some(ref default)) => { + highlight::render_with_highlighting( + &format!("{}: {:#} = {}", item.name.as_ref().unwrap(), ty, default), + None, + None, + None, + ) } _ => String::new(), } } -fn get_doc_value(item: &clean::Item) -> Option<&str> { - let x = item.doc_value(); - if x.is_none() { - match item.inner { - clean::AssociatedConstItem(_, _) => Some(""), - _ => None, - } - } else { - x - } -} - fn document_full(w: &mut fmt::Formatter, item: &clean::Item, - render_type: RenderType) -> fmt::Result { - if let Some(s) = get_doc_value(item) { - write!(w, "
{}
", - Markdown(&format!("{}{}", md_render_assoc_item(item), s), render_type))?; + render_type: RenderType, prefix: &str) -> fmt::Result { + if let Some(s) = item.doc_value() { + write!(w, "
{}{}
", prefix, Markdown(s, render_type))?; + } else if !prefix.is_empty() { + write!(w, "
{}
", prefix)?; } Ok(()) } @@ -2960,14 +2952,6 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi assoc_const(w, item, ty, default.as_ref(), link.anchor(&id))?; write!(w, "\n")?; } - clean::ConstantItem(ref c) => { - let id = derive_id(format!("{}.{}", item_type, name)); - let ns_id = derive_id(format!("{}.{}", name, item_type.name_space())); - write!(w, "

", id, item_type)?; - write!(w, "

\n")?; - } clean::AssociatedTypeItem(ref bounds, ref default) => { let id = derive_id(format!("{}.{}", item_type, name)); let ns_id = derive_id(format!("{}.{}", name, item_type.name_space())); @@ -2981,6 +2965,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi } if render_method_item || render_mode == RenderMode::Normal { + let prefix = render_assoc_const_value(item); if !is_default_item { if let Some(t) = trait_ { // The trait item may have been stripped so we might not @@ -2989,20 +2974,21 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi // We need the stability of the item from the trait // because impls can't have a stability. document_stability(w, cx, it)?; - if get_doc_value(item).is_some() { - document_full(w, item, cx.render_type)?; + if item.doc_value().is_some() { + document_full(w, item, cx.render_type, &prefix)?; } else { // In case the item isn't documented, // provide short documentation from the trait. - document_short(w, it, link, cx.render_type)?; + document_short(w, it, link, cx.render_type, &prefix)?; } } } else { - document(w, cx, item)?; + document_stability(w, cx, item)?; + document_full(w, item, cx.render_type, &prefix)?; } } else { document_stability(w, cx, item)?; - document_short(w, item, link, cx.render_type)?; + document_short(w, item, link, cx.render_type, &prefix)?; } } Ok(()) diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 8f6faabd157..41fd9efe61e 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -83,7 +83,8 @@ impl<'a> fold::DocFolder for Stripper<'a> { clean::TraitItem(..) | clean::FunctionItem(..) | clean::VariantItem(..) | clean::MethodItem(..) | clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) | - clean::ConstantItem(..) | clean::UnionItem(..) => { + clean::ConstantItem(..) | clean::UnionItem(..) | + clean::AssociatedConstItem(..) => { if i.def_id.is_local() { if !self.access_levels.is_exported(i.def_id) { return None; @@ -117,8 +118,7 @@ impl<'a> fold::DocFolder for Stripper<'a> { // Primitives are never stripped clean::PrimitiveItem(..) => {} - // Associated consts and types are never stripped - clean::AssociatedConstItem(..) | + // Associated types are never stripped clean::AssociatedTypeItem(..) => {} } diff --git a/src/test/rustdoc/assoc-consts.rs b/src/test/rustdoc/assoc-consts.rs index 04709407e58..8720d419a4d 100644 --- a/src/test/rustdoc/assoc-consts.rs +++ b/src/test/rustdoc/assoc-consts.rs @@ -16,10 +16,28 @@ pub trait Foo { // @has - '//*[@id="associatedconstant.FOO"]' 'const FOO: usize' // @has - '//*[@class="docblock"]' 'FOO: usize = 12' const FOO: usize = 12; + // @has - '//*[@id="associatedconstant.FOO_NO_DEFAULT"]' 'const FOO_NO_DEFAULT: bool' + const FOO_NO_DEFAULT: bool; + // @!has - FOO_HIDDEN + #[doc(hidden)] + const FOO_HIDDEN: u8 = 0; } pub struct Bar; +impl Foo for Bar { + // @has assoc_consts/struct.Bar.html '//code' 'impl Foo for Bar' + // @has - '//*[@id="associatedconstant.FOO"]' 'const FOO: usize' + // @has - '//*[@class="docblock"]' 'FOO: usize = 12' + const FOO: usize = 12; + // @has - '//*[@id="associatedconstant.FOO_NO_DEFAULT"]' 'const FOO_NO_DEFAULT: bool' + // @has - '//*[@class="docblock"]' 'FOO_NO_DEFAULT: bool = false' + const FOO_NO_DEFAULT: bool = false; + // @!has - FOO_HIDDEN + #[doc(hidden)] + const FOO_HIDDEN: u8 = 0; +} + impl Bar { // @has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.BAR"]' \ // 'const BAR: usize' @@ -44,3 +62,64 @@ impl Bar { // @has - '//*[@class="docblock"]' "F: fn(_: &(ToString + 'static)) = f" pub const F: fn(_: &(ToString + 'static)) = f; } + +impl Bar { + // @!has assoc_consts/struct.Bar.html 'BAR_PRIVATE' + const BAR_PRIVATE: char = 'a'; + // @!has assoc_consts/struct.Bar.html 'BAR_HIDDEN' + #[doc(hidden)] + pub const BAR_HIDDEN: &'static str = "a"; +} + +// @has assoc_consts/trait.Qux.html +pub trait Qux { + // @has - '//*[@id="associatedconstant.QUX0"]' 'const QUX0: u8' + // @has - '//*[@class="docblock"]' "Docs for QUX0 in trait." + /// Docs for QUX0 in trait. + const QUX0: u8; + // @has - '//*[@id="associatedconstant.QUX1"]' 'const QUX1: i8' + // @has - '//*[@class="docblock"]' "Docs for QUX1 in trait." + /// Docs for QUX1 in trait. + const QUX1: i8; + // @has - '//*[@id="associatedconstant.QUX_DEFAULT0"]' 'const QUX_DEFAULT0: u16' + // @has - '//*[@class="docblock"]' "QUX_DEFAULT0: u16 = 1" + // @has - '//*[@class="docblock"]' "Docs for QUX_DEFAULT0 in trait." + /// Docs for QUX_DEFAULT0 in trait. + const QUX_DEFAULT0: u16 = 1; + // @has - '//*[@id="associatedconstant.QUX_DEFAULT1"]' 'const QUX_DEFAULT1: i16' + // @has - '//*[@class="docblock"]' "QUX_DEFAULT1: i16 = 2" + // @has - '//*[@class="docblock"]' "Docs for QUX_DEFAULT1 in trait." + /// Docs for QUX_DEFAULT1 in trait. + const QUX_DEFAULT1: i16 = 2; + // @has - '//*[@id="associatedconstant.QUX_DEFAULT2"]' 'const QUX_DEFAULT2: u32' + // @has - '//*[@class="docblock"]' "QUX_DEFAULT2: u32 = 3" + // @has - '//*[@class="docblock"]' "Docs for QUX_DEFAULT2 in trait." + /// Docs for QUX_DEFAULT2 in trait. + const QUX_DEFAULT2: u32 = 3; +} + +// @has assoc_consts/struct.Bar.html '//code' 'impl Qux for Bar' +impl Qux for Bar { + // @has - '//*[@id="associatedconstant.QUX0"]' 'const QUX0: u8' + // @has - '//*[@class="docblock"]' "QUX0: u8 = 4" + // @has - '//*[@class="docblock"]' "Docs for QUX0 in trait." + /// Docs for QUX0 in trait. + const QUX0: u8 = 4; + // @has - '//*[@id="associatedconstant.QUX1"]' 'const QUX1: i8' + // @has - '//*[@class="docblock"]' "QUX1: i8 = 5" + // @has - '//*[@class="docblock"]' "Docs for QUX1 in impl." + /// Docs for QUX1 in impl. + const QUX1: i8 = 5; + // @has - '//*[@id="associatedconstant.QUX_DEFAULT0"]' 'const QUX_DEFAULT0: u16' + // @has - '//*[@class="docblock"]' "QUX_DEFAULT0: u16 = 6" + // @has - '//*[@class="docblock"]' "Docs for QUX_DEFAULT0 in trait." + const QUX_DEFAULT0: u16 = 6; + // @has - '//*[@id="associatedconstant.QUX_DEFAULT1"]' 'const QUX_DEFAULT1: i16' + // @has - '//*[@class="docblock"]' "QUX_DEFAULT1: i16 = 7" + // @has - '//*[@class="docblock"]' "Docs for QUX_DEFAULT1 in impl." + /// Docs for QUX_DEFAULT1 in impl. + const QUX_DEFAULT1: i16 = 7; + // @has - '//*[@id="associatedconstant.QUX_DEFAULT2"]' 'const QUX_DEFAULT2: u32' + // @has - '//*[@class="docblock"]' "QUX_DEFAULT2: u32 = 3" + // @has - '//*[@class="docblock"]' "Docs for QUX_DEFAULT2 in trait." +}