about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2016-05-21 09:08:09 +0530
committerManish Goregaokar <manishsmail@gmail.com>2016-05-21 09:08:09 +0530
commit3f4d91514733c81b41a2f7249cf7a87e997de2d7 (patch)
tree551e7ab3ac3328cebc3378b2437f495863e569ca
parent87a22885a0157ff820b0e4e1b7f4a48e06cdfb51 (diff)
parent9ce018bafbda6f1d8484adf4796a48e5cf9093bb (diff)
downloadrust-3f4d91514733c81b41a2f7249cf7a87e997de2d7.tar.gz
rust-3f4d91514733c81b41a2f7249cf7a87e997de2d7.zip
Rollup merge of #33679 - Manishearth:rustdoc-readmore-impls, r=alexcrichton
rustdoc: Add doc snippets for trait impls, with a read more link

The read more link only appears if the documentation is more than one line long.

![screenshot from 2016-05-17 06 54 14](https://cloud.githubusercontent.com/assets/1617736/15308544/4c2ba0ce-1bfc-11e6-9add-29de8dc7ac6e.png)

It currently does not appear on non-defaulted methods, since you can document them directly. I could make it so that default documentation gets forwarded if regular docs don't exist.

Fixes #33672

r? @alexcrichton

cc @steveklabnik
-rw-r--r--src/librustdoc/html/render.rs55
-rw-r--r--src/test/rustdoc/manual_impl.rs25
2 files changed, 62 insertions, 18 deletions
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index a103acadcf6..7357ff3abac 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1658,6 +1658,19 @@ fn document(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item) -> fmt::Re
     Ok(())
 }
 
+fn document_short(w: &mut fmt::Formatter, item: &clean::Item, link: AssocItemLink) -> fmt::Result {
+    if let Some(s) = item.doc_value() {
+        let markdown = if s.contains('\n') {
+            format!("{} [Read more]({})",
+                    &plain_summary_line(Some(s)), naive_assoc_href(item, link))
+        } else {
+            format!("{}", &plain_summary_line(Some(s)))
+        };
+        write!(w, "<div class='docblock'>{}</div>", Markdown(&markdown))?;
+    }
+    Ok(())
+}
+
 fn item_module(w: &mut fmt::Formatter, cx: &Context,
                item: &clean::Item, items: &[clean::Item]) -> fmt::Result {
     document(w, cx, item)?;
@@ -2555,8 +2568,9 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
     }
 
     fn doctraititem(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item,
-                    link: AssocItemLink, render_static: bool, is_default_item: bool,
-                    outer_version: Option<&str>) -> fmt::Result {
+                    link: AssocItemLink, render_static: bool,
+                    is_default_item: bool, outer_version: Option<&str>,
+                    trait_: Option<&clean::Trait>) -> fmt::Result {
         let shortty = shortty(item);
         let name = item.name.as_ref().unwrap();
 
@@ -2607,16 +2621,35 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
             _ => panic!("can't make docs for trait item with name {:?}", item.name)
         }
 
-        if !is_default_item && (!is_static || render_static) {
-            document(w, cx, item)
-        } else {
-            Ok(())
+        if !is_static || render_static {
+            if !is_default_item {
+
+                if item.doc_value().is_some() {
+                    document(w, cx, item)?;
+                } else {
+                    // In case the item isn't documented,
+                    // provide short documentation from the trait
+                    if let Some(t) = trait_ {
+                        if let Some(it) = t.items.iter()
+                                           .find(|i| i.name == item.name) {
+                            document_short(w, it, link)?;
+                        }
+                    }
+                }
+            } else {
+                document_short(w, item, link)?;
+            }
         }
+        Ok(())
     }
 
+    let traits = &cache().traits;
+    let trait_ = i.trait_did().and_then(|did| traits.get(&did));
+
     write!(w, "<div class='impl-items'>")?;
     for trait_item in &i.inner_impl().items {
-        doctraititem(w, cx, trait_item, link, render_header, false, outer_version)?;
+        doctraititem(w, cx, trait_item, link, render_header,
+                     false, outer_version, trait_)?;
     }
 
     fn render_default_items(w: &mut fmt::Formatter,
@@ -2634,17 +2667,15 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
             let assoc_link = AssocItemLink::GotoSource(did, &i.provided_trait_methods);
 
             doctraititem(w, cx, trait_item, assoc_link, render_static, true,
-                         outer_version)?;
+                         outer_version, None)?;
         }
         Ok(())
     }
 
     // If we've implemented a trait, then also emit documentation for all
     // default items which weren't overridden in the implementation block.
-    if let Some(did) = i.trait_did() {
-        if let Some(t) = cache().traits.get(&did) {
-            render_default_items(w, cx, t, &i.inner_impl(), render_header, outer_version)?;
-        }
+    if let Some(t) = trait_ {
+        render_default_items(w, cx, t, &i.inner_impl(), render_header, outer_version)?;
     }
     write!(w, "</div>")?;
     Ok(())
diff --git a/src/test/rustdoc/manual_impl.rs b/src/test/rustdoc/manual_impl.rs
index 5eccf97bb5f..befd3161ac4 100644
--- a/src/test/rustdoc/manual_impl.rs
+++ b/src/test/rustdoc/manual_impl.rs
@@ -21,13 +21,24 @@ pub trait T {
     fn b_method(&self) -> usize {
         self.a_method()
     }
+
+    /// Docs associated with the trait c_method definition.
+    ///
+    /// There is another line
+    fn c_method(&self) -> usize {
+        self.a_method()
+    }
 }
 
 // @has manual_impl/struct.S1.html '//*[@class="trait"]' 'T'
 // @has  - '//*[@class="docblock"]' 'Docs associated with the S1 trait implementation.'
 // @has  - '//*[@class="docblock"]' 'Docs associated with the S1 trait a_method implementation.'
 // @!has - '//*[@class="docblock"]' 'Docs associated with the trait a_method definition.'
-// @!has - '//*[@class="docblock"]' 'Docs associated with the trait b_method definition.'
+// @has - '//*[@class="docblock"]' 'Docs associated with the trait b_method definition.'
+// @has - '//*[@class="docblock"]' 'Docs associated with the trait b_method definition.'
+// @has - '//*[@class="docblock"]' 'Docs associated with the trait c_method definition.'
+// @!has - '//*[@class="docblock"]' 'There is another line'
+// @has - '//*[@class="docblock"]' 'Read more'
 pub struct S1(usize);
 
 /// Docs associated with the S1 trait implementation.
@@ -41,9 +52,11 @@ impl T for S1 {
 // @has manual_impl/struct.S2.html '//*[@class="trait"]' 'T'
 // @has  - '//*[@class="docblock"]' 'Docs associated with the S2 trait implementation.'
 // @has  - '//*[@class="docblock"]' 'Docs associated with the S2 trait a_method implementation.'
-// @has  - '//*[@class="docblock"]' 'Docs associated with the S2 trait b_method implementation.'
+// @has  - '//*[@class="docblock"]' 'Docs associated with the S2 trait c_method implementation.'
 // @!has - '//*[@class="docblock"]' 'Docs associated with the trait a_method definition.'
-// @!has - '//*[@class="docblock"]' 'Docs associated with the trait b_method definition.'
+// @!has - '//*[@class="docblock"]' 'Docs associated with the trait c_method definition.'
+// @has - '//*[@class="docblock"]' 'Docs associated with the trait b_method definition.'
+// @!has - '//*[@class="docblock"]' 'Read more'
 pub struct S2(usize);
 
 /// Docs associated with the S2 trait implementation.
@@ -53,8 +66,8 @@ impl T for S2 {
         self.0
     }
 
-    /// Docs associated with the S2 trait b_method implementation.
-    fn b_method(&self) -> usize {
+    /// Docs associated with the S2 trait c_method implementation.
+    fn c_method(&self) -> usize {
         5
     }
 }
@@ -62,7 +75,7 @@ impl T for S2 {
 // @has manual_impl/struct.S3.html '//*[@class="trait"]' 'T'
 // @has  - '//*[@class="docblock"]' 'Docs associated with the S3 trait implementation.'
 // @has  - '//*[@class="docblock"]' 'Docs associated with the S3 trait b_method implementation.'
-// @!has - '//*[@class="docblock"]' 'Docs associated with the trait a_method definition.'
+// @has - '//*[@class="docblock"]' 'Docs associated with the trait a_method definition.'
 pub struct S3(usize);
 
 /// Docs associated with the S3 trait implementation.