about summary refs log tree commit diff
path: root/src/librustdoc/html/render
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-10-16 02:10:19 +0200
committerGitHub <noreply@github.com>2020-10-16 02:10:19 +0200
commit71b0ea62354686553d180ad6f192c234c97501f2 (patch)
tree1e83eed12f37d235f9d849255bbf3443124f5022 /src/librustdoc/html/render
parent9b8c0eb107f75cf154b814cee10113c0359fefcf (diff)
parent4409cb2e3807c50d2e636ab293f10e6b8a87a7d4 (diff)
downloadrust-71b0ea62354686553d180ad6f192c234c97501f2.tar.gz
rust-71b0ea62354686553d180ad6f192c234c97501f2.zip
Rollup merge of #77672 - Nemo157:simplify-cfg, r=jyn514
Simplify doc-cfg rendering based on the current context

For sub-items on a page don't show cfg that has already been rendered on
a parent item. At its simplest this means not showing anything that is
shown in the portability message at the top of the page, but also for
things like fields of an enum variant if that variant itself is
cfg-gated then don't repeat those cfg on each field of the variant.

This does not touch trait implementation rendering, as that is more
complex and there are existing issues around how it deals with doc-cfg
that need to be fixed first.

### Screenshots, left is current, right is new:

![image](https://user-images.githubusercontent.com/81079/95387261-c2e6a200-08f0-11eb-90d4-0a9734acd922.png)

![image](https://user-images.githubusercontent.com/81079/95387458-06411080-08f1-11eb-81f7-5dd7f37695dd.png)

![image](https://user-images.githubusercontent.com/81079/95387702-6637b700-08f1-11eb-82f4-46b6cd9b24f2.png)

![image](https://user-images.githubusercontent.com/81079/95387905-b9aa0500-08f1-11eb-8d95-8b618d31d419.png)

![image](https://user-images.githubusercontent.com/81079/95388300-5bc9ed00-08f2-11eb-9ac9-b92cbdb60b89.png)

cc #43781
Diffstat (limited to 'src/librustdoc/html/render')
-rw-r--r--src/librustdoc/html/render/mod.rs104
1 files changed, 71 insertions, 33 deletions
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index f81ea0f6d46..22ae7af617f 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1763,11 +1763,11 @@ crate fn shorten(s: String) -> String {
     }
 }
 
-fn document(w: &mut Buffer, cx: &Context, item: &clean::Item) {
+fn document(w: &mut Buffer, cx: &Context, item: &clean::Item, parent: Option<&clean::Item>) {
     if let Some(ref name) = item.name {
         info!("Documenting {}", name);
     }
-    document_stability(w, cx, item, false);
+    document_stability(w, cx, item, false, parent);
     document_full(w, item, cx, "", false);
 }
 
@@ -1851,8 +1851,14 @@ fn document_full(w: &mut Buffer, item: &clean::Item, cx: &Context, prefix: &str,
     }
 }
 
-fn document_stability(w: &mut Buffer, cx: &Context, item: &clean::Item, is_hidden: bool) {
-    let stabilities = short_stability(item, cx);
+fn document_stability(
+    w: &mut Buffer,
+    cx: &Context,
+    item: &clean::Item,
+    is_hidden: bool,
+    parent: Option<&clean::Item>,
+) {
+    let stabilities = short_stability(item, cx, parent);
     if !stabilities.is_empty() {
         write!(w, "<div class='stability{}'>", if is_hidden { " hidden" } else { "" });
         for stability in stabilities {
@@ -1952,7 +1958,7 @@ pub fn compare_names(mut lhs: &str, mut rhs: &str) -> Ordering {
 }
 
 fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean::Item]) {
-    document(w, cx, item);
+    document(w, cx, item, None);
 
     let mut indices = (0..items.len()).filter(|i| !items[*i].is_stripped()).collect::<Vec<usize>>();
 
@@ -2111,7 +2117,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
                          <td class='docblock-short'>{stab_tags}{docs}</td>\
                      </tr>",
                     name = *myitem.name.as_ref().unwrap(),
-                    stab_tags = stability_tags(myitem),
+                    stab_tags = stability_tags(myitem, item),
                     docs = MarkdownSummaryLine(doc_value, &myitem.links()).into_string(),
                     class = myitem.type_(),
                     add = add,
@@ -2135,7 +2141,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
 
 /// Render the stability and deprecation tags that are displayed in the item's summary at the
 /// module level.
-fn stability_tags(item: &clean::Item) -> String {
+fn stability_tags(item: &clean::Item, parent: &clean::Item) -> String {
     let mut tags = String::new();
 
     fn tag_html(class: &str, title: &str, contents: &str) -> String {
@@ -2159,7 +2165,13 @@ fn stability_tags(item: &clean::Item) -> String {
         tags += &tag_html("unstable", "", "Experimental");
     }
 
-    if let Some(ref cfg) = item.attrs.cfg {
+    let cfg = match (&item.attrs.cfg, parent.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.attrs.cfg, cfg);
+    if let Some(ref cfg) = cfg {
         tags += &tag_html("portability", &cfg.render_long_plain(), &cfg.render_short_html());
     }
 
@@ -2168,7 +2180,7 @@ fn stability_tags(item: &clean::Item) -> String {
 
 /// 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) -> Vec<String> {
+fn short_stability(item: &clean::Item, cx: &Context, parent: Option<&clean::Item>) -> Vec<String> {
     let mut stability = vec![];
     let error_codes = cx.shared.codes;
 
@@ -2243,7 +2255,18 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
         stability.push(format!("<div class='stab unstable'>{}</div>", message));
     }
 
-    if let Some(ref cfg) = item.attrs.cfg {
+    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()));
     }
 
@@ -2282,7 +2305,7 @@ fn item_constant(w: &mut Buffer, cx: &Context, it: &clean::Item, c: &clean::Cons
     }
 
     write!(w, "</pre>");
-    document(w, cx, it)
+    document(w, cx, it, None)
 }
 
 fn item_static(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Static) {
@@ -2296,7 +2319,7 @@ fn item_static(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Static
         name = it.name.as_ref().unwrap(),
         typ = s.type_.print()
     );
-    document(w, cx, it)
+    document(w, cx, it, None)
 }
 
 fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Function) {
@@ -2329,7 +2352,7 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
             .print(),
         spotlight = spotlight_decl(&f.decl),
     );
-    document(w, cx, it)
+    document(w, cx, it, None)
 }
 
 fn render_implementor(
@@ -2354,6 +2377,7 @@ fn render_implementor(
         w,
         cx,
         implementor,
+        None,
         AssocItemLink::Anchor(None),
         RenderMode::Normal,
         implementor.impl_item.stable_since().as_deref(),
@@ -2383,6 +2407,7 @@ fn render_impls(
                 &mut buffer,
                 cx,
                 i,
+                Some(containing_item),
                 assoc_link,
                 RenderMode::Normal,
                 containing_item.stable_since().as_deref(),
@@ -2502,7 +2527,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
     });
 
     // Trait documentation
-    document(w, cx, it);
+    document(w, cx, it, None);
 
     fn write_small_section_header(w: &mut Buffer, id: &str, title: &str, extra_content: &str) {
         write!(
@@ -2520,6 +2545,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
 
     fn trait_item(w: &mut Buffer, cx: &Context, m: &clean::Item, t: &clean::Item) {
         let name = m.name.as_ref().unwrap();
+        info!("Documenting {} on {}", name, t.name.as_deref().unwrap_or_default());
         let item_type = m.type_();
         let id = cx.derive_id(format!("{}.{}", item_type, name));
         write!(w, "<h3 id='{id}' class='method'><code>", id = id,);
@@ -2527,7 +2553,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
         write!(w, "</code>");
         render_stability_since(w, m, t);
         write!(w, "</h3>");
-        document(w, cx, m);
+        document(w, cx, m, Some(t));
     }
 
     if !types.is_empty() {
@@ -2628,6 +2654,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
                     w,
                     cx,
                     &implementor,
+                    None,
                     assoc_link,
                     RenderMode::Normal,
                     implementor.impl_item.stable_since().as_deref(),
@@ -2890,7 +2917,7 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct
         write!(w, "</pre>")
     });
 
-    document(w, cx, it);
+    document(w, cx, it, None);
     let mut fields = s
         .fields
         .iter()
@@ -2925,7 +2952,7 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct
                     name = field.name.as_ref().unwrap(),
                     ty = ty.print()
                 );
-                document(w, cx, field);
+                document(w, cx, field, Some(it));
             }
         }
     }
@@ -2940,7 +2967,7 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union,
         write!(w, "</pre>")
     });
 
-    document(w, cx, it);
+    document(w, cx, it, None);
     let mut fields = s
         .fields
         .iter()
@@ -2972,7 +2999,7 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union,
             if let Some(stability_class) = field.stability_class() {
                 write!(w, "<span class='stab {stab}'></span>", stab = stability_class);
             }
-            document(w, cx, field);
+            document(w, cx, field, Some(it));
         }
     }
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
@@ -3027,7 +3054,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca
         write!(w, "</pre>")
     });
 
-    document(w, cx, it);
+    document(w, cx, it, None);
     if !e.variants.is_empty() {
         write!(
             w,
@@ -3060,7 +3087,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca
                 }
             }
             write!(w, "</code></div>");
-            document(w, cx, variant);
+            document(w, cx, variant, Some(it));
             document_non_exhaustive(w, variant);
 
             use crate::clean::{Variant, VariantKind};
@@ -3095,7 +3122,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca
                             f = field.name.as_ref().unwrap(),
                             t = ty.print()
                         );
-                        document(w, cx, field);
+                        document(w, cx, field, Some(variant));
                     }
                 }
                 write!(w, "</div></div>");
@@ -3293,6 +3320,10 @@ fn render_assoc_items(
     what: AssocItemRender<'_>,
     cache: &Cache,
 ) {
+    info!(
+        "Documenting associated items of {}",
+        containing_item.name.as_deref().unwrap_or_default()
+    );
     let v = match cache.impls.get(&it) {
         Some(v) => v,
         None => return,
@@ -3327,6 +3358,7 @@ fn render_assoc_items(
                 w,
                 cx,
                 i,
+                Some(containing_item),
                 AssocItemLink::Anchor(None),
                 render_mode,
                 containing_item.stable_since().as_deref(),
@@ -3518,6 +3550,7 @@ fn render_impl(
     w: &mut Buffer,
     cx: &Context,
     i: &Impl,
+    parent: Option<&clean::Item>,
     link: AssocItemLink<'_>,
     render_mode: RenderMode,
     outer_version: Option<&str>,
@@ -3600,6 +3633,7 @@ fn render_impl(
         w: &mut Buffer,
         cx: &Context,
         item: &clean::Item,
+        parent: Option<&clean::Item>,
         link: AssocItemLink<'_>,
         render_mode: RenderMode,
         is_default_item: bool,
@@ -3684,7 +3718,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);
+                        document_stability(w, cx, it, is_hidden, parent);
                         if item.doc_value().is_some() {
                             document_full(w, item, cx, "", is_hidden);
                         } else if show_def_docs {
@@ -3694,13 +3728,13 @@ fn render_impl(
                         }
                     }
                 } else {
-                    document_stability(w, cx, item, is_hidden);
+                    document_stability(w, cx, item, is_hidden, parent);
                     if show_def_docs {
                         document_full(w, item, cx, "", is_hidden);
                     }
                 }
             } else {
-                document_stability(w, cx, item, is_hidden);
+                document_stability(w, cx, item, is_hidden, parent);
                 if show_def_docs {
                     document_short(w, item, link, "", is_hidden);
                 }
@@ -3717,6 +3751,7 @@ fn render_impl(
             w,
             cx,
             trait_item,
+            parent,
             link,
             render_mode,
             false,
@@ -3732,6 +3767,7 @@ fn render_impl(
         cx: &Context,
         t: &clean::Trait,
         i: &clean::Impl,
+        parent: Option<&clean::Item>,
         render_mode: RenderMode,
         outer_version: Option<&str>,
         show_def_docs: bool,
@@ -3749,6 +3785,7 @@ fn render_impl(
                 w,
                 cx,
                 trait_item,
+                parent,
                 assoc_link,
                 render_mode,
                 true,
@@ -3771,6 +3808,7 @@ fn render_impl(
                 cx,
                 t,
                 &i.inner_impl(),
+                parent,
                 render_mode,
                 outer_version,
                 show_def_docs,
@@ -3799,7 +3837,7 @@ fn item_opaque_ty(
         bounds = bounds(&t.bounds, false)
     );
 
-    document(w, cx, it);
+    document(w, cx, it, None);
 
     // Render any items associated directly to this alias, as otherwise they
     // won't be visible anywhere in the docs. It would be nice to also show
@@ -3826,7 +3864,7 @@ fn item_trait_alias(
         bounds(&t.bounds, true)
     );
 
-    document(w, cx, it);
+    document(w, cx, it, None);
 
     // Render any items associated directly to this alias, as otherwise they
     // won't be visible anywhere in the docs. It would be nice to also show
@@ -3847,7 +3885,7 @@ fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typed
         type_ = t.type_.print()
     );
 
-    document(w, cx, it);
+    document(w, cx, it, None);
 
     // Render any items associated directly to this alias, as otherwise they
     // won't be visible anywhere in the docs. It would be nice to also show
@@ -3866,7 +3904,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item, cache: &Cac
         it.name.as_ref().unwrap(),
     );
 
-    document(w, cx, it);
+    document(w, cx, it, None);
 
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
 }
@@ -4511,7 +4549,7 @@ fn item_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Macro)
             None,
         ))
     });
-    document(w, cx, it)
+    document(w, cx, it, None)
 }
 
 fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::ProcMacro) {
@@ -4541,16 +4579,16 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::Pr
             write!(w, "</pre>");
         }
     }
-    document(w, cx, it)
+    document(w, cx, it, None)
 }
 
 fn item_primitive(w: &mut Buffer, cx: &Context, it: &clean::Item, cache: &Cache) {
-    document(w, cx, it);
+    document(w, cx, it, None);
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
 }
 
 fn item_keyword(w: &mut Buffer, cx: &Context, it: &clean::Item) {
-    document(w, cx, it)
+    document(w, cx, it, None)
 }
 
 crate const BASIC_KEYWORDS: &str = "rust, rustlang, rust-lang";