about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustdoc/html/render/mod.rs95
-rw-r--r--src/test/rustdoc/associated-consts.rs31
2 files changed, 110 insertions, 16 deletions
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index dc5aec3b084..69c5c2c4abc 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1811,23 +1811,53 @@ fn get_next_url(used_links: &mut FxHashSet<String>, url: String) -> String {
     format!("{}-{}", url, add)
 }
 
+struct SidebarLink {
+    name: Symbol,
+    url: String,
+}
+
+impl fmt::Display for SidebarLink {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "<a href=\"#{}\">{}</a>", self.url, self.name)
+    }
+}
+
+impl PartialEq for SidebarLink {
+    fn eq(&self, other: &Self) -> bool {
+        self.url == other.url
+    }
+}
+
+impl Eq for SidebarLink {}
+
+impl PartialOrd for SidebarLink {
+    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for SidebarLink {
+    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+        self.url.cmp(&other.url)
+    }
+}
+
 fn get_methods(
     i: &clean::Impl,
     for_deref: bool,
     used_links: &mut FxHashSet<String>,
     deref_mut: bool,
     tcx: TyCtxt<'_>,
-) -> Vec<String> {
+) -> Vec<SidebarLink> {
     i.items
         .iter()
         .filter_map(|item| match item.name {
-            Some(ref name) if !name.is_empty() && item.is_method() => {
+            Some(name) if !name.is_empty() && item.is_method() => {
                 if !for_deref || should_render_item(item, deref_mut, tcx) {
-                    Some(format!(
-                        "<a href=\"#{}\">{}</a>",
-                        get_next_url(used_links, format!("method.{}", name)),
-                        name
-                    ))
+                    Some(SidebarLink {
+                        name,
+                        url: get_next_url(used_links, format!("method.{}", name)),
+                    })
                 } else {
                     None
                 }
@@ -1837,6 +1867,22 @@ fn get_methods(
         .collect::<Vec<_>>()
 }
 
+fn get_associated_constants(
+    i: &clean::Impl,
+    used_links: &mut FxHashSet<String>,
+) -> Vec<SidebarLink> {
+    i.items
+        .iter()
+        .filter_map(|item| match item.name {
+            Some(name) if !name.is_empty() && item.is_associated_const() => Some(SidebarLink {
+                name,
+                url: get_next_url(used_links, format!("associatedconstant.{}", name)),
+            }),
+            _ => None,
+        })
+        .collect::<Vec<_>>()
+}
+
 // The point is to url encode any potential character from a type with genericity.
 fn small_url_encode(s: String) -> String {
     let mut st = String::new();
@@ -1881,23 +1927,40 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
 
         {
             let used_links_bor = &mut used_links;
-            let mut ret = v
+            let mut assoc_consts = v
+                .iter()
+                .flat_map(|i| get_associated_constants(i.inner_impl(), used_links_bor))
+                .collect::<Vec<_>>();
+            if !assoc_consts.is_empty() {
+                // We want links' order to be reproducible so we don't use unstable sort.
+                assoc_consts.sort();
+
+                out.push_str(
+                    "<h3 class=\"sidebar-title\">\
+                        <a href=\"#implementations\">Associated Constants</a>\
+                     </h3>\
+                     <div class=\"sidebar-links\">",
+                );
+                for line in assoc_consts {
+                    write!(out, "{}", line);
+                }
+                out.push_str("</div>");
+            }
+            let mut methods = v
                 .iter()
                 .filter(|i| i.inner_impl().trait_.is_none())
-                .flat_map(move |i| {
-                    get_methods(i.inner_impl(), false, used_links_bor, false, cx.tcx())
-                })
+                .flat_map(|i| get_methods(i.inner_impl(), false, used_links_bor, false, cx.tcx()))
                 .collect::<Vec<_>>();
-            if !ret.is_empty() {
+            if !methods.is_empty() {
                 // We want links' order to be reproducible so we don't use unstable sort.
-                ret.sort();
+                methods.sort();
 
                 out.push_str(
                     "<h3 class=\"sidebar-title\"><a href=\"#implementations\">Methods</a></h3>\
                      <div class=\"sidebar-links\">",
                 );
-                for line in ret {
-                    out.push_str(&line);
+                for line in methods {
+                    write!(out, "{}", line);
                 }
                 out.push_str("</div>");
             }
@@ -2032,7 +2095,7 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V
                 ret.sort();
                 out.push_str("<div class=\"sidebar-links\">");
                 for link in ret {
-                    out.push_str(&link);
+                    write!(out, "{}", link);
                 }
                 out.push_str("</div>");
             }
diff --git a/src/test/rustdoc/associated-consts.rs b/src/test/rustdoc/associated-consts.rs
new file mode 100644
index 00000000000..6ae5e20632e
--- /dev/null
+++ b/src/test/rustdoc/associated-consts.rs
@@ -0,0 +1,31 @@
+#![crate_name = "foo"]
+
+pub trait Trait {
+    const FOO: u32 = 12;
+
+    fn foo();
+}
+
+pub struct Bar;
+
+// @has 'foo/struct.Bar.html'
+// @has - '//h3[@class="sidebar-title"]' 'Associated Constants'
+// @has - '//div[@class="sidebar-elems"]//div[@class="sidebar-links"]/a' 'FOO'
+impl Trait for Bar {
+    const FOO: u32 = 1;
+
+    fn foo() {}
+}
+
+pub enum Foo {
+    A,
+}
+
+// @has 'foo/enum.Foo.html'
+// @has - '//h3[@class="sidebar-title"]' 'Associated Constants'
+// @has - '//div[@class="sidebar-elems"]//div[@class="sidebar-links"]/a' 'FOO'
+impl Trait for Foo {
+    const FOO: u32 = 1;
+
+    fn foo() {}
+}