From 3dbb741a4b54516e6979f85f4847361413a1b4a3 Mon Sep 17 00:00:00 2001 From: Kazuyoshi Kato Date: Tue, 4 Sep 2018 01:44:19 -0700 Subject: [PATCH 1/3] rustdoc: Sort implementors Fixes #53812 --- src/librustdoc/html/render.rs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 867b2a329057b..54c746cae410f 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2300,17 +2300,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), } @@ -2701,6 +2705,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, @@ -2904,9 +2916,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, "

@@ -4715,6 +4730,7 @@ fn test_name_sorting() { "Fruit1", "Fruit01", "Fruit2", "Fruit02", "Fruit20", + "Fruit30x", "Fruit100", "Pear"]; let mut sorted = names.to_owned(); From bbcb6339aa6f1062a220ce5d16fea3b645c32281 Mon Sep 17 00:00:00 2001 From: Kazuyoshi Kato Date: Fri, 14 Sep 2018 22:42:44 -0700 Subject: [PATCH 2/3] Add a test to prevent regression The way it defines implementations is unrealistic though. --- src/test/rustdoc/issue-53812.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/test/rustdoc/issue-53812.rs diff --git a/src/test/rustdoc/issue-53812.rs b/src/test/rustdoc/issue-53812.rs new file mode 100644 index 0000000000000..f0113d13bb4f4 --- /dev/null +++ b/src/test/rustdoc/issue-53812.rs @@ -0,0 +1,26 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub trait MyIterator { +} + +pub struct MyStruct(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]>' +array_impls! { 10 3 2 1 0 } From 2fe450370319c30756a716e0525cc6d23046f104 Mon Sep 17 00:00:00 2001 From: Kazuyoshi Kato Date: Sun, 16 Sep 2018 00:39:12 -0700 Subject: [PATCH 3/3] Check the remaining nodes --- src/test/rustdoc/issue-53812.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/rustdoc/issue-53812.rs b/src/test/rustdoc/issue-53812.rs index f0113d13bb4f4..60d19fbcd1a20 100644 --- a/src/test/rustdoc/issue-53812.rs +++ b/src/test/rustdoc/issue-53812.rs @@ -23,4 +23,8 @@ macro_rules! array_impls { } // @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 }