]> git.lizzy.rs Git - rust.git/blobdiff - src/librustdoc/html/render.rs
Auto merge of #43651 - petrochenkov:foreign-life, r=eddyb
[rust.git] / src / librustdoc / html / render.rs
index e89bd7aae9bf12f53713d47f651353d2206f89eb..4e3181759f999aafb26458776c5bebcf25bc0b2f 100644 (file)
@@ -762,6 +762,7 @@ fn collect(path: &Path, krate: &str,
             }
         };
 
+        let mut have_impls = false;
         let mut implementors = format!(r#"implementors["{}"] = ["#, krate.name);
         for imp in imps {
             // If the trait and implementation are in the same crate, then
@@ -769,10 +770,21 @@ fn collect(path: &Path, krate: &str,
             // going on). If they're in different crates then the crate defining
             // the trait will be interested in our implementation.
             if imp.def_id.krate == did.krate { continue }
+            // If the implementation is from another crate then that crate
+            // should add it.
+            if !imp.def_id.is_local() { continue }
+            have_impls = true;
             write!(implementors, "{},", as_json(&imp.impl_.to_string())).unwrap();
         }
         implementors.push_str("];");
 
+        // Only create a js file if we have impls to add to it. If the trait is
+        // documented locally though we always create the file to avoid dead
+        // links.
+        if !have_impls && !cache.paths.contains_key(&did) {
+            continue;
+        }
+
         let mut mydst = dst.clone();
         for part in &remote_path[..remote_path.len() - 1] {
             mydst.push(part);
@@ -1950,6 +1962,14 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
         stability.push(format!("<div class='stab deprecated'>{}</div>", text))
     }
 
+    if let Some(ref cfg) = item.attrs.cfg {
+        stability.push(format!("<div class='stab portability'>{}</div>", if show_reason {
+            cfg.render_long_html()
+        } else {
+            cfg.render_short_html()
+        }));
+    }
+
     stability
 }
 
@@ -2141,8 +2161,8 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
 
     if !types.is_empty() {
         write!(w, "
-            <h2 id='associated-types' class='section-header'>
-              <a href='#associated-types'>Associated Types</a>
+            <h2 id='associated-types' class='small-section-header'>
+              Associated Types<a href='#associated-types' class='anchor'></a>
             </h2>
             <div class='methods'>
         ")?;
@@ -2154,8 +2174,8 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
 
     if !consts.is_empty() {
         write!(w, "
-            <h2 id='associated-const' class='section-header'>
-              <a href='#associated-const'>Associated Constants</a>
+            <h2 id='associated-const' class='small-section-header'>
+              Associated Constants<a href='#associated-const' class='anchor'></a>
             </h2>
             <div class='methods'>
         ")?;
@@ -2168,8 +2188,8 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
     // Output the documentation for each function individually
     if !required.is_empty() {
         write!(w, "
-            <h2 id='required-methods' class='section-header'>
-              <a href='#required-methods'>Required Methods</a>
+            <h2 id='required-methods' class='small-section-header'>
+              Required Methods<a href='#required-methods' class='anchor'></a>
             </h2>
             <div class='methods'>
         ")?;
@@ -2180,8 +2200,8 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
     }
     if !provided.is_empty() {
         write!(w, "
-            <h2 id='provided-methods' class='section-header'>
-              <a href='#provided-methods'>Provided Methods</a>
+            <h2 id='provided-methods' class='small-section-header'>
+              Provided Methods<a href='#provided-methods' class='anchor'></a>
             </h2>
             <div class='methods'>
         ")?;
@@ -2196,8 +2216,8 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
 
     let cache = cache();
     write!(w, "
-        <h2 id='implementors' class='section-header'>
-          <a href='#implementors'>Implementors</a>
+        <h2 id='implementors' class='small-section-header'>
+          Implementors<a href='#implementors' class='anchor'></a>
         </h2>
         <ul class='item-list' id='implementors-list'>
     ")?;
@@ -2235,6 +2255,13 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
                 _ => false,
             };
             fmt_impl_for_trait_page(&implementor.impl_, w, use_absolute)?;
+            for it in &implementor.impl_.items {
+                if let clean::TypedefItem(ref tydef, _) = it.inner {
+                    write!(w, "<span class=\"where fmt-newline\">  ")?;
+                    assoc_type(w, it, &vec![], Some(&tydef.type_), AssocItemLink::Anchor(None))?;
+                    write!(w, ";</span>")?;
+                }
+            }
             writeln!(w, "</code></li>")?;
         }
     }
@@ -2429,8 +2456,8 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
     }).peekable();
     if let doctree::Plain = s.struct_type {
         if fields.peek().is_some() {
-            write!(w, "<h2 id='fields' class='fields section-header'>
-                       <a href='#fields'>Fields</a></h2>")?;
+            write!(w, "<h2 id='fields' class='fields small-section-header'>
+                       Fields<a href='#fields' class='anchor'></a></h2>")?;
             for (field, ty) in fields {
                 let id = derive_id(format!("{}.{}",
                                            ItemType::StructField,
@@ -2478,8 +2505,8 @@ fn item_union(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
         }
     }).peekable();
     if fields.peek().is_some() {
-        write!(w, "<h2 id='fields' class='fields section-header'>
-                   <a href='#fields'>Fields</a></h2>")?;
+        write!(w, "<h2 id='fields' class='fields small-section-header'>
+                   Fields<a href='#fields' class='anchor'></a></h2>")?;
         for (field, ty) in fields {
             write!(w, "<span id='{shortty}.{name}' class=\"{shortty}\"><code>{name}: {ty}</code>
                        </span>",
@@ -2551,8 +2578,8 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
 
     document(w, cx, it)?;
     if !e.variants.is_empty() {
-        write!(w, "<h2 id='variants' class='variants section-header'>
-                   <a href='#variants'>Variants</a></h2>\n")?;
+        write!(w, "<h2 id='variants' class='variants small-section-header'>
+                   Variants<a href='#variants' class='anchor'></a></h2>\n")?;
         for variant in &e.variants {
             let id = derive_id(format!("{}.{}",
                                        ItemType::Variant,
@@ -2824,16 +2851,16 @@ fn render_assoc_items(w: &mut fmt::Formatter,
         let render_mode = match what {
             AssocItemRender::All => {
                 write!(w, "
-                    <h2 id='methods' class='section-header'>
-                      <a href='#methods'>Methods</a>
+                    <h2 id='methods' class='small-section-header'>
+                      Methods<a href='#methods' class='anchor'></a>
                     </h2>
                 ")?;
                 RenderMode::Normal
             }
             AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
                 write!(w, "
-                    <h2 id='deref-methods' class='section-header'>
-                      <a href='#deref-methods'>Methods from {}&lt;Target = {}&gt;</a>
+                    <h2 id='deref-methods' class='small-section-header'>
+                      Methods from {}&lt;Target = {}&gt;<a href='#deref-methods' class='anchor'></a>
                     </h2>
                 ", trait_, type_)?;
                 RenderMode::ForDeref { mut_: deref_mut_ }
@@ -2858,8 +2885,8 @@ fn render_assoc_items(w: &mut fmt::Formatter,
             render_deref_methods(w, cx, impl_, containing_item, has_deref_mut)?;
         }
         write!(w, "
-            <h2 id='implementations' class='section-header'>
-              <a href='#implementations'>Trait Implementations</a>
+            <h2 id='implementations' class='small-section-header'>
+              Trait Implementations<a href='#implementations' class='anchor'></a>
             </h2>
         ")?;
         for i in &traits {
@@ -2962,7 +2989,15 @@ fn doc_impl_item(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item,
                     write!(w, "<code>")?;
                     render_assoc_item(w, item, link.anchor(&id), ItemType::Impl)?;
                     write!(w, "</code>")?;
-                    render_stability_since_raw(w, item.stable_since(), outer_version)?;
+                    if let Some(l) = (Item { cx, item }).src_href() {
+                        write!(w, "</span><span class='out-of-band'>")?;
+                        write!(w, "<div class='ghost'></div>")?;
+                        render_stability_since_raw(w, item.stable_since(), outer_version)?;
+                        write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>",
+                               l, "goto source code")?;
+                    } else {
+                        render_stability_since_raw(w, item.stable_since(), outer_version)?;
+                    }
                     write!(w, "</span></h4>\n")?;
                 }
             }