about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustdoc/html/render/mod.rs72
-rw-r--r--src/librustdoc/html/static/main.js10
-rw-r--r--src/test/rustdoc/doc-cfg-traits.rs124
3 files changed, 174 insertions, 32 deletions
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index eebb07f0476..fc0ce4b1f09 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2251,6 +2251,22 @@ fn stability_tags(item: &clean::Item, parent: &clean::Item) -> String {
     tags
 }
 
+fn portability(item: &clean::Item, parent: Option<&clean::Item>) -> Option<String> {
+    let cfg = match (&item.attrs.cfg, parent.and_then(|p| p.attrs.cfg.as_ref())) {
+        (Some(cfg), Some(parent_cfg)) => cfg.simplify_with(parent_cfg),
+        (cfg, _) => cfg.as_deref().cloned(),
+    };
+
+    debug!(
+        "Portability {:?} - {:?} = {:?}",
+        item.attrs.cfg,
+        parent.and_then(|p| p.attrs.cfg.as_ref()),
+        cfg
+    );
+
+    Some(format!("<div class=\"stab portability\">{}</div>", cfg?.render_long_html()))
+}
+
 /// Render the stability and/or deprecation warning that is displayed at the top of the item's
 /// documentation.
 fn short_stability(item: &clean::Item, cx: &Context, parent: Option<&clean::Item>) -> Vec<String> {
@@ -2328,19 +2344,8 @@ fn short_stability(item: &clean::Item, cx: &Context, parent: Option<&clean::Item
         stability.push(format!("<div class=\"stab unstable\">{}</div>", message));
     }
 
-    let cfg = match (&item.attrs.cfg, parent.and_then(|p| p.attrs.cfg.as_ref())) {
-        (Some(cfg), Some(parent_cfg)) => cfg.simplify_with(parent_cfg),
-        (cfg, _) => cfg.as_deref().cloned(),
-    };
-
-    debug!(
-        "Portability {:?} - {:?} = {:?}",
-        item.attrs.cfg,
-        parent.and_then(|p| p.attrs.cfg.as_ref()),
-        cfg
-    );
-    if let Some(cfg) = cfg {
-        stability.push(format!("<div class=\"stab portability\">{}</div>", cfg.render_long_html()));
+    if let Some(portability) = portability(item, parent) {
+        stability.push(portability);
     }
 
     stability
@@ -2431,6 +2436,7 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
 fn render_implementor(
     cx: &Context,
     implementor: &Impl,
+    parent: &clean::Item,
     w: &mut Buffer,
     implementor_dups: &FxHashMap<&str, (DefId, bool)>,
     aliases: &[String],
@@ -2450,7 +2456,7 @@ fn render_implementor(
         w,
         cx,
         implementor,
-        None,
+        parent,
         AssocItemLink::Anchor(None),
         RenderMode::Normal,
         implementor.impl_item.stable_since().as_deref(),
@@ -2480,7 +2486,7 @@ fn render_impls(
                 &mut buffer,
                 cx,
                 i,
-                Some(containing_item),
+                containing_item,
                 assoc_link,
                 RenderMode::Normal,
                 containing_item.stable_since().as_deref(),
@@ -2727,7 +2733,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
                     w,
                     cx,
                     &implementor,
-                    None,
+                    it,
                     assoc_link,
                     RenderMode::Normal,
                     implementor.impl_item.stable_since().as_deref(),
@@ -2749,7 +2755,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
             "<div class=\"item-list\" id=\"implementors-list\">",
         );
         for implementor in concrete {
-            render_implementor(cx, implementor, w, &implementor_dups, &[], cache);
+            render_implementor(cx, implementor, it, w, &implementor_dups, &[], cache);
         }
         write_loading_content(w, "</div>");
 
@@ -2764,6 +2770,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
                 render_implementor(
                     cx,
                     implementor,
+                    it,
                     w,
                     &implementor_dups,
                     &collect_paths_for_type(implementor.inner_impl().for_.clone()),
@@ -3430,7 +3437,7 @@ fn render_assoc_items(
                 w,
                 cx,
                 i,
-                Some(containing_item),
+                containing_item,
                 AssocItemLink::Anchor(None),
                 render_mode,
                 containing_item.stable_since().as_deref(),
@@ -3622,7 +3629,7 @@ fn render_impl(
     w: &mut Buffer,
     cx: &Context,
     i: &Impl,
-    parent: Option<&clean::Item>,
+    parent: &clean::Item,
     link: AssocItemLink<'_>,
     render_mode: RenderMode,
     outer_version: Option<&str>,
@@ -3635,6 +3642,9 @@ fn render_impl(
     aliases: &[String],
     cache: &Cache,
 ) {
+    let traits = &cache.traits;
+    let trait_ = i.trait_did().map(|did| &traits[&did]);
+
     if render_mode == RenderMode::Normal {
         let id = cx.derive_id(match i.inner_impl().trait_ {
             Some(ref t) => {
@@ -3687,6 +3697,13 @@ fn render_impl(
             );
         }
         write!(w, "</h3>");
+
+        if trait_.is_some() {
+            if let Some(portability) = portability(&i.impl_item, Some(parent)) {
+                write!(w, "<div class=\"stability\">{}</div>", portability);
+            }
+        }
+
         if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) {
             let mut ids = cx.id_map.borrow_mut();
             write!(
@@ -3709,7 +3726,7 @@ fn render_impl(
         w: &mut Buffer,
         cx: &Context,
         item: &clean::Item,
-        parent: Option<&clean::Item>,
+        parent: &clean::Item,
         link: AssocItemLink<'_>,
         render_mode: RenderMode,
         is_default_item: bool,
@@ -3794,7 +3811,7 @@ fn render_impl(
                     if let Some(it) = t.items.iter().find(|i| i.name == item.name) {
                         // We need the stability of the item from the trait
                         // because impls can't have a stability.
-                        document_stability(w, cx, it, is_hidden, parent);
+                        document_stability(w, cx, it, is_hidden, Some(parent));
                         if item.doc_value().is_some() {
                             document_full(w, item, cx, "", is_hidden);
                         } else if show_def_docs {
@@ -3804,13 +3821,13 @@ fn render_impl(
                         }
                     }
                 } else {
-                    document_stability(w, cx, item, is_hidden, parent);
+                    document_stability(w, cx, item, is_hidden, Some(parent));
                     if show_def_docs {
                         document_full(w, item, cx, "", is_hidden);
                     }
                 }
             } else {
-                document_stability(w, cx, item, is_hidden, parent);
+                document_stability(w, cx, item, is_hidden, Some(parent));
                 if show_def_docs {
                     document_short(w, item, link, "", is_hidden);
                 }
@@ -3818,16 +3835,13 @@ fn render_impl(
         }
     }
 
-    let traits = &cache.traits;
-    let trait_ = i.trait_did().map(|did| &traits[&did]);
-
     write!(w, "<div class=\"impl-items\">");
     for trait_item in &i.inner_impl().items {
         doc_impl_item(
             w,
             cx,
             trait_item,
-            parent,
+            if trait_.is_some() { &i.impl_item } else { parent },
             link,
             render_mode,
             false,
@@ -3843,7 +3857,7 @@ fn render_impl(
         cx: &Context,
         t: &clean::Trait,
         i: &clean::Impl,
-        parent: Option<&clean::Item>,
+        parent: &clean::Item,
         render_mode: RenderMode,
         outer_version: Option<&str>,
         show_def_docs: bool,
@@ -3884,7 +3898,7 @@ fn render_impl(
                 cx,
                 t,
                 &i.inner_impl(),
-                parent,
+                &i.impl_item,
                 render_mode,
                 outer_version,
                 show_def_docs,
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index cbf15cd0b6e..b8377dc1569 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -2439,12 +2439,13 @@ function defocusSearchBar() {
 
         var func = function(e) {
             var next = e.nextElementSibling;
+            if (next && hasClass(next, "stability")) {
+              next = next.nextElementSibling;
+            }
             if (!next) {
                 return;
             }
-            if (hasClass(next, "docblock") === true ||
-                (hasClass(next, "stability") === true &&
-                 hasClass(next.nextElementSibling, "docblock") === true)) {
+            if (hasClass(next, "docblock")) {
                 var newToggle = toggle.cloneNode(true);
                 insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]);
                 if (hideMethodDocs === true && hasClass(e, "method") === true) {
@@ -2455,6 +2456,9 @@ function defocusSearchBar() {
 
         var funcImpl = function(e) {
             var next = e.nextElementSibling;
+            if (next && hasClass(next, "stability")) {
+                next = next.nextElementSibling;
+            }
             if (next && hasClass(next, "docblock")) {
                 next = next.nextElementSibling;
             }
diff --git a/src/test/rustdoc/doc-cfg-traits.rs b/src/test/rustdoc/doc-cfg-traits.rs
new file mode 100644
index 00000000000..13407b2c791
--- /dev/null
+++ b/src/test/rustdoc/doc-cfg-traits.rs
@@ -0,0 +1,124 @@
+#![crate_name = "myrmecophagous"]
+#![feature(doc_cfg, associated_type_defaults)]
+
+// @has 'myrmecophagous/index.html'
+// @count   - '//*[@class="stab portability"]' 2
+// @matches - '//*[@class="stab portability"]' '^jurisconsult$'
+// @matches - '//*[@class="stab portability"]' '^quarter$'
+
+pub trait Lea {}
+
+// @has 'myrmecophagous/trait.Vortoscope.html'
+// @count   - '//*[@class="stab portability"]' 6
+// @matches - '//*[@class="stab portability"]' 'crate feature zibib'
+// @matches - '//*[@class="stab portability"]' 'crate feature poriform'
+// @matches - '//*[@class="stab portability"]' 'crate feature ethopoeia'
+// @matches - '//*[@class="stab portability"]' 'crate feature lea'
+// @matches - '//*[@class="stab portability"]' 'crate feature unit'
+// @matches - '//*[@class="stab portability"]' 'crate feature quarter'
+pub trait Vortoscope {
+    type Batology = ();
+
+    #[doc(cfg(feature = "zibib"))]
+    type Zibib = ();
+
+    const YAHRZEIT: () = ();
+
+    #[doc(cfg(feature = "poriform"))]
+    const PORIFORM: () = ();
+
+    fn javanais() {}
+
+    #[doc(cfg(feature = "ethopoeia"))]
+    fn ethopoeia() {}
+}
+
+#[doc(cfg(feature = "lea"))]
+impl<T: Lea> Vortoscope for T {}
+
+#[doc(cfg(feature = "unit"))]
+impl Vortoscope for () {}
+
+// @has 'myrmecophagous/trait.Jurisconsult.html'
+// @count   - '//*[@class="stab portability"]' 7
+// @matches - '//*[@class="stab portability"]' 'crate feature jurisconsult'
+// @matches - '//*[@class="stab portability"]' 'crate feature lithomancy'
+// @matches - '//*[@class="stab portability"]' 'crate feature boodle'
+// @matches - '//*[@class="stab portability"]' 'crate feature mistetch'
+// @matches - '//*[@class="stab portability"]' 'crate feature lea'
+// @matches - '//*[@class="stab portability"]' 'crate feature unit'
+// @matches - '//*[@class="stab portability"]' 'crate feature quarter'
+#[doc(cfg(feature = "jurisconsult"))]
+pub trait Jurisconsult {
+    type Urbanist = ();
+
+    #[doc(cfg(feature = "lithomancy"))]
+    type Lithomancy = ();
+
+    const UNIFILAR: () = ();
+
+    #[doc(cfg(feature = "boodle"))]
+    const BOODLE: () = ();
+
+    fn mersion() {}
+
+    #[doc(cfg(feature = "mistetch"))]
+    fn mistetch() {}
+}
+
+#[doc(cfg(feature = "lea"))]
+impl<T: Lea> Jurisconsult for T {}
+
+#[doc(cfg(feature = "unit"))]
+impl Jurisconsult for () {}
+
+// @has 'myrmecophagous/struct.Ultimogeniture.html'
+// @count   - '//*[@class="stab portability"]' 8
+//
+// @matches - '//*[@class="stab portability"]' 'crate feature zibib'
+// @matches - '//*[@class="stab portability"]' 'crate feature poriform'
+// @matches - '//*[@class="stab portability"]' 'crate feature ethopoeia'
+//
+// @matches - '//*[@class="stab portability"]' 'crate feature jurisconsult'
+// @matches - '//*[@class="stab portability"]' 'crate feature lithomancy'
+// @matches - '//*[@class="stab portability"]' 'crate feature boodle'
+// @matches - '//*[@class="stab portability"]' 'crate feature mistetch'
+//
+// @matches - '//*[@class="stab portability"]' 'crate feature copy'
+#[derive(Clone)]
+pub struct Ultimogeniture;
+
+impl Vortoscope for Ultimogeniture {}
+
+#[doc(cfg(feature = "jurisconsult"))]
+impl Jurisconsult for Ultimogeniture {}
+
+#[doc(cfg(feature = "copy"))]
+impl Copy for Ultimogeniture {}
+
+// @has 'myrmecophagous/struct.Quarter.html'
+// @count   - '//*[@class="stab portability"]' 9
+// @matches - '//*[@class="stab portability"]' 'crate feature quarter'
+//
+// @matches - '//*[@class="stab portability"]' 'crate feature zibib'
+// @matches - '//*[@class="stab portability"]' 'crate feature poriform'
+// @matches - '//*[@class="stab portability"]' 'crate feature ethopoeia'
+//
+// @matches - '//*[@class="stab portability"]' 'crate feature jurisconsult'
+// @matches - '//*[@class="stab portability"]' 'crate feature lithomancy'
+// @matches - '//*[@class="stab portability"]' 'crate feature boodle'
+// @matches - '//*[@class="stab portability"]' 'crate feature mistetch'
+//
+// @matches - '//*[@class="stab portability"]' 'crate feature copy'
+#[doc(cfg(feature = "quarter"))]
+#[derive(Clone)]
+pub struct Quarter;
+
+#[doc(cfg(feature = "quarter"))]
+impl Vortoscope for Quarter {}
+
+#[doc(cfg(all(feature = "jurisconsult", feature = "quarter")))]
+impl Jurisconsult for Quarter {}
+
+#[doc(cfg(all(feature = "copy", feature = "quarter")))]
+impl Copy for Quarter {}