]> git.lizzy.rs Git - rust.git/commitdiff
spotlight Iterator/Read/Write impls on function return types
authorQuietMisdreavus <grey@quietmisdreavus.net>
Wed, 4 Oct 2017 20:51:35 +0000 (15:51 -0500)
committerGuillaume Gomez <guillaume1.gomez@gmail.com>
Fri, 17 Nov 2017 21:50:15 +0000 (22:50 +0100)
src/libcore/iter/iterator.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/main.js
src/librustdoc/html/static/rustdoc.css
src/libstd/io/mod.rs

index 6a4dba31b62a926a09c959cd17d3aa294899feb5..a2bd15bdf05c7e52769dbfb4590f39d2a38f535e 100644 (file)
@@ -30,6 +30,7 @@ fn _assert_is_object_safe(_: &Iterator<Item=()>) {}
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling \
                             `.iter()` or a similar method"]
+#[doc(spotlight)]
 pub trait Iterator {
     /// The type of the elements being iterated over.
     #[stable(feature = "rust1", since = "1.0.0")]
index 9fb9437e1bc9a717d8d796512932c269deecd272..ce04be67aa4bc45021251f57c99423718f523a21 100644 (file)
@@ -140,11 +140,13 @@ pub fn build_external_trait(cx: &DocContext, did: DefId) -> clean::Trait {
     let generics = (cx.tcx.generics_of(did), &predicates).clean(cx);
     let generics = filter_non_trait_generics(did, generics);
     let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
+    let is_spotlight = load_attrs(cx, did).has_doc_flag("spotlight");
     clean::Trait {
         unsafety: cx.tcx.trait_def(did).unsafety,
         generics,
         items: trait_items,
         bounds: supertrait_bounds,
+        is_spotlight,
     }
 }
 
index 1d107c169b04625dfe3e7c75e8866f931e7c7744..69226239c96e80421368b895c4f1ab52631ec9f1 100644 (file)
@@ -151,7 +151,7 @@ fn clean(&self, cx: &DocContext) -> Crate {
         match module.inner {
             ModuleItem(ref module) => {
                 for it in &module.items {
-                    if it.is_extern_crate() && it.attrs.has_doc_masked() {
+                    if it.is_extern_crate() && it.attrs.has_doc_flag("masked") {
                         masked_crates.insert(it.def_id.krate);
                     }
                 }
@@ -596,12 +596,12 @@ fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> {
         None
     }
 
-    pub fn has_doc_masked(&self) -> bool {
+    pub fn has_doc_flag(&self, flag: &str) -> bool {
         for attr in &self.other_attrs {
             if !attr.check_name("doc") { continue; }
 
             if let Some(items) = attr.meta_item_list() {
-                if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name("masked")) {
+                if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name(flag)) {
                     return true;
                 }
             }
@@ -1331,19 +1331,31 @@ fn clean(&self, cx: &DocContext) -> FunctionRetTy {
     }
 }
 
+impl GetDefId for FunctionRetTy {
+    fn def_id(&self) -> Option<DefId> {
+        match *self {
+            Return(ref ty) => ty.def_id(),
+            DefaultReturn => None,
+        }
+    }
+}
+
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Trait {
     pub unsafety: hir::Unsafety,
     pub items: Vec<Item>,
     pub generics: Generics,
     pub bounds: Vec<TyParamBound>,
+    pub is_spotlight: bool,
 }
 
 impl Clean<Item> for doctree::Trait {
     fn clean(&self, cx: &DocContext) -> Item {
+        let attrs = self.attrs.clean(cx);
+        let is_spotlight = attrs.has_doc_flag("spotlight");
         Item {
             name: Some(self.name.clean(cx)),
-            attrs: self.attrs.clean(cx),
+            attrs: attrs,
             source: self.whence.clean(cx),
             def_id: cx.tcx.hir.local_def_id(self.id),
             visibility: self.vis.clean(cx),
@@ -1354,6 +1366,7 @@ fn clean(&self, cx: &DocContext) -> Item {
                 items: self.items.clean(cx),
                 generics: self.generics.clean(cx),
                 bounds: self.bounds.clean(cx),
+                is_spotlight: is_spotlight,
             }),
         }
     }
index e848a8d3853b9aef8e29cc35ff0250f2755c699f..d43a73c986453bad0b614feb36320d52db9308a7 100644 (file)
@@ -1816,7 +1816,8 @@ 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)?;
-    let prefix = render_assoc_const_value(item);
+    let mut prefix = render_assoc_const_value(item);
+    prefix.push_str(&render_spotlight_traits(item)?);
     document_full(w, item, cx, &prefix)?;
     Ok(())
 }
@@ -2603,10 +2604,10 @@ fn assoc_const(w: &mut fmt::Formatter,
     Ok(())
 }
 
-fn assoc_type(w: &mut fmt::Formatter, it: &clean::Item,
-              bounds: &Vec<clean::TyParamBound>,
-              default: Option<&clean::Type>,
-              link: AssocItemLink) -> fmt::Result {
+fn assoc_type<W: fmt::Write>(w: &mut W, it: &clean::Item,
+                             bounds: &Vec<clean::TyParamBound>,
+                             default: Option<&clean::Type>,
+                             link: AssocItemLink) -> fmt::Result {
     write!(w, "type <a href='{}' class=\"type\">{}</a>",
            naive_assoc_href(it, link),
            it.name.as_ref().unwrap())?;
@@ -3236,6 +3237,62 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool) -> bool {
     }
 }
 
+fn render_spotlight_traits(item: &clean::Item) -> Result<String, fmt::Error> {
+    let mut out = String::new();
+
+    match item.inner {
+        clean::FunctionItem(clean::Function { ref decl, .. }) |
+        clean::TyMethodItem(clean::TyMethod { ref decl, .. }) |
+        clean::MethodItem(clean::Method { ref decl, .. }) |
+        clean::ForeignFunctionItem(clean::Function { ref decl, .. }) => {
+            out = spotlight_decl(decl)?;
+        }
+        _ => {}
+    }
+
+    Ok(out)
+}
+
+fn spotlight_decl(decl: &clean::FnDecl) -> Result<String, fmt::Error> {
+    let mut out = String::new();
+
+    if let Some(did) = decl.output.def_id() {
+        let c = cache();
+        if let Some(impls) = c.impls.get(&did) {
+            for i in impls {
+                let impl_ = i.inner_impl();
+                if impl_.trait_.def_id().and_then(|d| c.traits.get(&d))
+                                        .map_or(false, |t| t.is_spotlight) {
+                    if out.is_empty() {
+                        out.push_str("<span class=\"docblock autohide\">");
+                        out.push_str(&format!("<h3>Important traits for {}</h3>", impl_.for_));
+                        out.push_str("<code class=\"spotlight\">");
+                    }
+
+                    //use the "where" class here to make it small
+                    out.push_str(&format!("<span class=\"where fmt-newline\">{}</span>", impl_));
+                    let t_did = impl_.trait_.def_id().unwrap();
+                    for it in &impl_.items {
+                        if let clean::TypedefItem(ref tydef, _) = it.inner {
+                            out.push_str("<span class=\"where fmt-newline\">    ");
+                            assoc_type(&mut out, it, &vec![],
+                                       Some(&tydef.type_),
+                                       AssocItemLink::GotoSource(t_did, &FxHashSet()))?;
+                            out.push_str(";</span>");
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    if !out.is_empty() {
+        out.push_str("</code></span>");
+    }
+
+    Ok(out)
+}
+
 fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLink,
                render_mode: RenderMode, outer_version: Option<&str>,
                show_def_docs: bool) -> fmt::Result {
@@ -3270,6 +3327,7 @@ fn doc_impl_item(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item,
                      trait_: Option<&clean::Trait>, show_def_docs: bool) -> fmt::Result {
         let item_type = item.type_();
         let name = item.name.as_ref().unwrap();
+        let mut method_prefix: Option<String> = None;
 
         let render_method_item: bool = match render_mode {
             RenderMode::Normal => true,
@@ -3277,7 +3335,8 @@ fn doc_impl_item(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item,
         };
 
         match item.inner {
-            clean::MethodItem(..) | clean::TyMethodItem(..) => {
+            clean::MethodItem(clean::Method { ref decl, .. }) |
+            clean::TyMethodItem(clean::TyMethod{ ref decl, .. }) => {
                 // Only render when the method is not static or we allow static methods
                 if render_method_item {
                     let id = derive_id(format!("{}.{}", item_type, name));
@@ -3297,6 +3356,7 @@ fn doc_impl_item(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item,
                         render_stability_since_raw(w, item.stable_since(), outer_version)?;
                     }
                     write!(w, "</span></h4>\n")?;
+                    method_prefix = Some(spotlight_decl(decl)?);
                 }
             }
             clean::TypedefItem(ref tydef, _) => {
@@ -3328,7 +3388,12 @@ fn doc_impl_item(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item,
         }
 
         if render_method_item || render_mode == RenderMode::Normal {
-            let prefix = render_assoc_const_value(item);
+            let mut prefix = render_assoc_const_value(item);
+
+            if let Some(method_prefix) = method_prefix {
+                prefix.push_str(&method_prefix);
+            }
+
             if !is_default_item {
                 if let Some(t) = trait_ {
                     // The trait item may have been stripped so we might not
index 8d0faf261f6c934df9314726a828edd992f69a47..49dfa891c0adee1aa3c3dbba6fc4b4cb597b5264 100644 (file)
     }
 
     onEach(document.getElementById('main').getElementsByClassName('docblock'), function(e) {
-        if (e.parentNode.id === "main") {
-            e.parentNode.insertBefore(createToggle(), e);
-        }
+        e.parentNode.insertBefore(createToggle(), e);
     });
 
     onEach(document.getElementsByClassName('docblock'), function(e) {
index 55acc575152371a5ac05b11a30ad3f17aa5b91ab..29bec231b84fc4665f9c3efc549c279062b118b2 100644 (file)
@@ -141,9 +141,12 @@ code, pre {
        border-radius: 3px;
        padding: 0 0.2em;
 }
-.docblock pre code, .docblock-short pre code {
+.docblock pre code, .docblock-short pre code, .docblock code.spotlight {
        padding: 0;
 }
+.docblock code.spotlight :last-child {
+       padding-bottom: 0.6em;
+}
 pre {
        padding: 14px;
 }
index 57f8c39756e3c8bad6acb6e5836e5a8c307de1e9..7eeb1bd61e34c0138d22ee1beb8418fcb835076f 100644 (file)
@@ -450,6 +450,7 @@ fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize>
 /// # }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
+#[doc(spotlight)]
 pub trait Read {
     /// Pull some bytes from this source into the specified buffer, returning
     /// how many bytes were read.
@@ -968,6 +969,7 @@ pub fn initialize(&self, buf: &mut [u8]) {
 /// # }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
+#[doc(spotlight)]
 pub trait Write {
     /// Write a buffer into this object, returning how many bytes were written.
     ///