From 41f6e97a445f736ab437b2f64756b967cf69d763 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 21 Oct 2013 11:33:04 -0700 Subject: [PATCH] rustdoc: Render default methods for impls as well This does not work for cross-crate implementations of traits. Cross-crate implementations are a separate issue that should be addressed separately. Basically when an implementation of an external trait is detected, the trait would have to be loaded at that time (or possibly sooner...). Rustdoc currently doesn't have the proper infrastructure for adding this. Closes #9985 cc #9999 --- src/librustdoc/html/render.rs | 85 +++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 29 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 53c3cf3a10c7..8b089e76f3a0 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -149,10 +149,9 @@ pub struct Cache { /// This map contains information about all known traits of this crate. /// Implementations of a crate should inherit the documentation of the - /// parent trait if no extra documentation is specified, and this map is - /// keyed on trait id with a value of a 'method name => documentation' - /// mapping. - traits: HashMap>, + /// parent trait if no extra documentation is specified, and default methods + /// should show up in documentation about trait implementations. + traits: HashMap, /// When rendering traits, it's often useful to be able to list all /// implementors of the trait, and this mapping is exactly, that: a mapping @@ -488,18 +487,7 @@ impl DocFolder for Cache { // trait match item.inner { clean::TraitItem(ref t) => { - let mut dox = HashMap::new(); - for meth in t.methods.iter() { - let it = meth.item(); - match it.doc_value() { - None => {} - Some(s) => { - dox.insert(it.name.get_ref().to_owned(), - s.to_owned()); - } - } - } - self.traits.insert(item.id, dox); + self.traits.insert(item.id, t.clone()); } _ => {} } @@ -1480,18 +1468,25 @@ fn render_impl(w: &mut io::Writer, i: &clean::Impl, dox: &Option<~str>) { } None => {} } - write!(w, "
"); - for meth in i.methods.iter() { + + fn docmeth(w: &mut io::Writer, item: &clean::Item) -> bool { write!(w, "

", - *meth.name.get_ref()); - render_method(w, meth, false); + *item.name.get_ref()); + render_method(w, item, false); write!(w, "

\n"); - match meth.doc_value() { + match item.doc_value() { Some(s) => { write!(w, "
{}
", Markdown(s)); - continue + true } - None => {} + None => false + } + } + + write!(w, "
"); + for meth in i.methods.iter() { + if docmeth(w, meth) { + continue } // No documentation? Attempt to slurp in the trait's documentation @@ -1501,13 +1496,19 @@ fn render_impl(w: &mut io::Writer, i: &clean::Impl, dox: &Option<~str>) { }; do local_data::get(cache_key) |cache| { do cache.unwrap().read |cache| { - let name = meth.name.get_ref().as_slice(); match cache.traits.find(&trait_id) { - Some(m) => { - match m.find_equiv(&name) { - Some(s) => { - write!(w, "
{}
", - Markdown(s.as_slice())); + Some(t) => { + let name = meth.name.clone(); + match t.methods.iter().find(|t| t.item().name == name) { + Some(method) => { + match method.item().doc_value() { + Some(s) => { + write!(w, + "
{}
", + Markdown(s)); + } + None => {} + } } None => {} } @@ -1517,6 +1518,32 @@ fn render_impl(w: &mut io::Writer, i: &clean::Impl, dox: &Option<~str>) { } } } + + // If we've implemented a trait, then also emit documentation for all + // default methods which weren't overridden in the implementation block. + match trait_id { + None => {} + Some(id) => { + do local_data::get(cache_key) |cache| { + do cache.unwrap().read |cache| { + match cache.traits.find(&id) { + Some(t) => { + for method in t.methods.iter() { + let n = method.item().name.clone(); + match i.methods.iter().find(|m| m.name == n) { + Some(*) => continue, + None => {} + } + + docmeth(w, method.item()); + } + } + None => {} + } + } + } + } + } write!(w, "
"); }