]> git.lizzy.rs Git - rust.git/commitdiff
Don't display full blanket implementation and put it into its own section
authorGuillaume Gomez <guillaume1.gomez@gmail.com>
Fri, 27 Jul 2018 20:59:16 +0000 (22:59 +0200)
committerGuillaume Gomez <guillaume1.gomez@gmail.com>
Sat, 28 Jul 2018 13:18:38 +0000 (15:18 +0200)
src/librustdoc/clean/auto_trait.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/format.rs
src/librustdoc/html/render.rs
src/test/rustdoc/generic-impl.rs
src/test/rustdoc/synthetic_auto/basic.rs
src/test/rustdoc/synthetic_auto/manual.rs

index 556d8462d3b966467d7b2f0d977e1d98976f2a1c..d0d5713ec0a3fc7b2010d7f7b49e20622fc66f9b 100644 (file)
@@ -198,7 +198,7 @@ pub fn get_auto_trait_impls<F>(
                                          .collect();
 
                             let ty = self.get_real_ty(def_id, def_ctor, &real_name, generics);
-                            let predicates = infcx.tcx.predicates_of(def_id);
+                            let predicates = infcx.tcx.predicates_of(impl_def_id);
 
                             traits.push(Item {
                                 source: infcx.tcx.def_span(impl_def_id).clean(self.cx),
@@ -218,7 +218,9 @@ pub fn get_auto_trait_impls<F>(
                                                     .collect::<Vec<_>>()
                                                     .clean(self.cx),
                                     polarity: None,
-                                    synthetic: true,
+                                    synthetic: false,
+                                    blanket_impl: Some(infcx.tcx.type_of(impl_def_id)
+                                                                .clean(self.cx)),
                                 }),
                             });
                             debug!("{:?} => {}", trait_ref, may_apply);
@@ -345,6 +347,7 @@ fn get_auto_trait_impl_for<F>(
                     items: Vec::new(),
                     polarity,
                     synthetic: true,
+                    blanket_impl: None,
                 }),
             });
         }
index fe93dd16ffda91e3aefd3408c0fbc54b67dbf9ea..9245ef3cf507bd89cbcce6c3ff643de81bdbaf51 100644 (file)
@@ -414,6 +414,7 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
             items: trait_items,
             polarity: Some(polarity.clean(cx)),
             synthetic: false,
+            blanket_impl: None,
         }),
         source: tcx.def_span(did).clean(cx),
         name: None,
index 68842522223c5bdd34e28ce0be2267b40ec0b6da..89f328016ec54299372893f66f85104394039d43 100644 (file)
@@ -3881,6 +3881,7 @@ pub struct Impl {
     pub items: Vec<Item>,
     pub polarity: Option<ImplPolarity>,
     pub synthetic: bool,
+    pub blanket_impl: Option<Type>,
 }
 
 pub fn get_auto_traits_with_node_id(cx: &DocContext, id: ast::NodeId, name: String) -> Vec<Item> {
@@ -3948,6 +3949,7 @@ fn clean(&self, cx: &DocContext) -> Vec<Item> {
                 items,
                 polarity: Some(self.polarity.clean(cx)),
                 synthetic: false,
+                blanket_impl: None,
             })
         });
         ret
index 2377354b85f6bf587e41d17a2cab2ea8db90afa4..9c7354a7c63fc196593b4b1c609e0d94ad19150c 100644 (file)
@@ -769,7 +769,11 @@ fn fmt_impl(i: &clean::Impl,
         write!(f, " for ")?;
     }
 
-    fmt_type(&i.for_, f, use_absolute)?;
+    if let Some(ref ty) = i.blanket_impl {
+        fmt_type(ty, f, use_absolute)?;
+    } else {
+        fmt_type(&i.for_, f, use_absolute)?;
+    }
 
     fmt::Display::fmt(&WhereClause { gens: &i.generics, indent: 0, end_newline: true }, f)?;
     Ok(())
index fd39202b87c1a3ac22ce8634365500c07c810b30..200c961cf5dc2c4711bd7f2e38419c774558529b 100644 (file)
@@ -177,7 +177,7 @@ pub enum ExternalLocation {
 }
 
 /// Metadata about implementations for a type or trait.
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub struct Impl {
     pub impl_item: clean::Item,
 }
@@ -2900,18 +2900,18 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)?;
 
     let cache = cache();
-    let impl_header = "
-        <h2 id='implementors' class='small-section-header'>
-          Implementors<a href='#implementors' class='anchor'></a>
-        </h2>
-        <ul class='item-list' id='implementors-list'>
+    let impl_header = "\
+        <h2 id='implementors' class='small-section-header'>\
+          Implementors<a href='#implementors' class='anchor'></a>\
+        </h2>\
+        <ul class='item-list' id='implementors-list'>\
     ";
 
-    let synthetic_impl_header = "
-        <h2 id='synthetic-implementors' class='small-section-header'>
-          Auto implementors<a href='#synthetic-implementors' class='anchor'></a>
-        </h2>
-        <ul class='item-list' id='synthetic-implementors-list'>
+    let synthetic_impl_header = "\
+        <h2 id='synthetic-implementors' class='small-section-header'>\
+          Auto implementors<a href='#synthetic-implementors' class='anchor'></a>\
+        </h2>\
+        <ul class='item-list' id='synthetic-implementors-list'>\
     ";
 
     let mut synthetic_types = Vec::new();
@@ -2942,9 +2942,9 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
                                          .map_or(true, |d| cache.paths.contains_key(&d)));
 
 
-        let (synthetic, concrete) = local.iter()
-            .partition::<Vec<_>, _>(|i| i.inner_impl().synthetic);
-
+        let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = local.iter()
+            .filter(|i| i.inner_impl().blanket_impl.is_none())
+            .partition(|i| i.inner_impl().synthetic);
 
         if !foreign.is_empty() {
             write!(w, "
@@ -3626,9 +3626,12 @@ fn render_assoc_items(w: &mut fmt::Formatter,
             render_deref_methods(w, cx, impl_, containing_item, has_deref_mut)?;
         }
 
-        let (synthetic, concrete) = traits
+        let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = traits
             .iter()
-            .partition::<Vec<_>, _>(|t| t.inner_impl().synthetic);
+            .partition(|t| t.inner_impl().synthetic);
+        let (blanket_impl, concrete) = concrete
+            .into_iter()
+            .partition(|t| t.inner_impl().blanket_impl.is_some());
 
         struct RendererStruct<'a, 'b, 'c>(&'a Context, Vec<&'b &'b Impl>, &'c clean::Item);
 
@@ -3658,6 +3661,18 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
             render_impls(cx, w, &synthetic, containing_item)?;
             write!(w, "</div>")?;
         }
+
+        if !blanket_impl.is_empty() {
+            write!(w, "\
+                <h2 id='blanket-implementations' class='small-section-header'>\
+                  Blanket Implementations\
+                  <a href='#blanket-implementations' class='anchor'></a>\
+                </h2>\
+                <div id='blanket-implementations-list'>\
+            ")?;
+            render_impls(cx, w, &blanket_impl, containing_item)?;
+            write!(w, "</div>")?;
+        }
     }
     Ok(())
 }
@@ -4203,12 +4218,16 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
                            .collect::<String>()
             };
 
-            let (synthetic, concrete) = v
+            let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = v
                 .iter()
                 .partition::<Vec<_>, _>(|i| i.inner_impl().synthetic);
+            let (blanket_impl, concrete): (Vec<&Impl>, Vec<&Impl>) = concrete
+                .into_iter()
+                .partition::<Vec<_>, _>(|i| i.inner_impl().blanket_impl.is_some());
 
             let concrete_format = format_impls(concrete);
             let synthetic_format = format_impls(synthetic);
+            let blanket_format = format_impls(blanket_impl);
 
             if !concrete_format.is_empty() {
                 out.push_str("<a class=\"sidebar-title\" href=\"#implementations\">\
@@ -4221,6 +4240,12 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
                               Auto Trait Implementations</a>");
                 out.push_str(&format!("<div class=\"sidebar-links\">{}</div>", synthetic_format));
             }
+
+            if !blanket_format.is_empty() {
+                out.push_str("<a class=\"sidebar-title\" href=\"#blanket-implementations\">\
+                              Blanket Implementations</a>");
+                out.push_str(&format!("<div class=\"sidebar-links\">{}</div>", blanket_format));
+            }
         }
     }
 
index e69a3277d7f2bd88e7f8ff117d795636eb7e650f..e2665fd8f375b5bc136c3142a3927b209946d16d 100644 (file)
 
 use std::fmt;
 
-// @!has foo/struct.Bar.html '//h3[@id="impl-ToString"]//code' 'impl<T> ToString for Bar'
+// @!has foo/struct.Bar.html '//h3[@id="impl-ToString"]//code' 'impl<T> ToString for T'
 pub struct Bar;
 
-// @has foo/struct.Foo.html '//h3[@id="impl-ToString"]//code' 'impl<T> ToString for Foo'
+// @has foo/struct.Foo.html '//h3[@id="impl-ToString"]//code' 'impl<T> ToString for T'
 pub struct Foo;
 
 impl fmt::Display for Foo {
index f9a6c2607cd771e5d8d93222a3b1eb9f898770c9..8ff84d11a5009874ced4f941da3ce7777e42a839 100644 (file)
@@ -12,7 +12,7 @@
 // @has - '//code' 'impl<T> Send for Foo<T> where T: Send'
 // @has - '//code' 'impl<T> Sync for Foo<T> where T: Sync'
 // @count - '//*[@id="implementations-list"]/*[@class="impl"]' 0
-// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 9
+// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 2
 pub struct Foo<T> {
     field: T,
 }
index 8c7f9d8cc659e9f4a3fe4c95be26b7a68c73482c..ef6797ecf3c54277ce872fd01541907a3e46d171 100644 (file)
@@ -16,7 +16,7 @@
 // 'impl<T> Send for Foo<T>'
 //
 // @count - '//*[@id="implementations-list"]/*[@class="impl"]' 1
-// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 8
+// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 1
 pub struct Foo<T> {
     field: T,
 }