about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2018-09-16 12:25:41 +0200
committerGitHub <noreply@github.com>2018-09-16 12:25:41 +0200
commit3466d8044fdd9a72dc07c79fd74659f95acc5c1e (patch)
tree4e88a452f39defa5e3fb593e146868954f968569
parentf4819878cd4e397cc3fff9679e3255af1adb2430 (diff)
parent2fe450370319c30756a716e0525cc6d23046f104 (diff)
downloadrust-3466d8044fdd9a72dc07c79fd74659f95acc5c1e.tar.gz
rust-3466d8044fdd9a72dc07c79fd74659f95acc5c1e.zip
Rollup merge of #53941 - kzys:sort-impls, r=GuillaumeGomez
rustdoc: Sort implementors

Fixes #53812
-rw-r--r--src/librustdoc/html/render.rs24
-rw-r--r--src/test/rustdoc/issue-53812.rs30
2 files changed, 50 insertions, 4 deletions
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index d4e22dd91d7..75311d93851 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -2301,17 +2301,21 @@ fn document_non_exhaustive(w: &mut fmt::Formatter, item: &clean::Item) -> fmt::R
 }
 
 fn name_key(name: &str) -> (&str, u64, usize) {
+    let end = name.bytes()
+        .rposition(|b| b.is_ascii_digit()).map_or(name.len(), |i| i + 1);
+
     // find number at end
-    let split = name.bytes().rposition(|b| b < b'0' || b'9' < b).map_or(0, |s| s + 1);
+    let split = name[0..end].bytes()
+        .rposition(|b| !b.is_ascii_digit()).map_or(0, |i| i + 1);
 
     // count leading zeroes
     let after_zeroes =
-        name[split..].bytes().position(|b| b != b'0').map_or(name.len(), |extra| split + extra);
+        name[split..end].bytes().position(|b| b != b'0').map_or(name.len(), |extra| split + extra);
 
     // sort leading zeroes last
     let num_zeroes = after_zeroes - split;
 
-    match name[split..].parse() {
+    match name[split..end].parse() {
         Ok(n) => (&name[..split], n, num_zeroes),
         Err(_) => (name, 0, num_zeroes),
     }
@@ -2702,6 +2706,14 @@ fn bounds(t_bounds: &[clean::GenericBound]) -> String {
     bounds
 }
 
+fn compare_impl<'a, 'b>(lhs: &'a &&Impl, rhs: &'b &&Impl) -> Ordering {
+    let lhs = format!("{}", lhs.inner_impl());
+    let rhs = format!("{}", rhs.inner_impl());
+
+    // lhs and rhs are formatted as HTML, which may be unnecessary
+    name_key(&lhs).cmp(&name_key(&rhs))
+}
+
 fn item_trait(
     w: &mut fmt::Formatter,
     cx: &Context,
@@ -2905,9 +2917,12 @@ fn item_trait(
                                          .map_or(true, |d| cache.paths.contains_key(&d)));
 
 
-        let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = local.iter()
+        let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) = local.iter()
             .partition(|i| i.inner_impl().synthetic);
 
+        synthetic.sort_by(compare_impl);
+        concrete.sort_by(compare_impl);
+
         if !foreign.is_empty() {
             write!(w, "
                 <h2 id='foreign-impls' class='small-section-header'>
@@ -4716,6 +4731,7 @@ fn test_name_sorting() {
                  "Fruit1", "Fruit01",
                  "Fruit2", "Fruit02",
                  "Fruit20",
+                 "Fruit30x",
                  "Fruit100",
                  "Pear"];
     let mut sorted = names.to_owned();
diff --git a/src/test/rustdoc/issue-53812.rs b/src/test/rustdoc/issue-53812.rs
new file mode 100644
index 00000000000..60d19fbcd1a
--- /dev/null
+++ b/src/test/rustdoc/issue-53812.rs
@@ -0,0 +1,30 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub trait MyIterator {
+}
+
+pub struct MyStruct<T>(T);
+
+macro_rules! array_impls {
+    ($($N:expr)+) => {
+        $(
+            impl<'a, T> MyIterator for &'a MyStruct<[T; $N]> {
+            }
+        )+
+    }
+}
+
+// @has issue_53812/trait.MyIterator.html '//*[@id="implementors-list"]//h3[1]' 'MyStruct<[T; 0]>'
+// @has - '//*[@id="implementors-list"]//h3[2]' 'MyStruct<[T; 1]>'
+// @has - '//*[@id="implementors-list"]//h3[3]' 'MyStruct<[T; 2]>'
+// @has - '//*[@id="implementors-list"]//h3[4]' 'MyStruct<[T; 3]>'
+// @has - '//*[@id="implementors-list"]//h3[5]' 'MyStruct<[T; 10]>'
+array_impls! { 10 3 2 1 0 }