diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index e6c64ef8b4220..cbb5fed8c4d09 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -4,8 +4,7 @@ //! various types in `rustdoc::clean`. //! //! These implementations all emit HTML. As an internal implementation detail, -//! some of them support an alternate format that emits text, but that should -//! not be used external to this module. +//! some of them support an alternate format that emits plain text. use std::cmp::Ordering; use std::fmt::{self, Display, Write}; @@ -184,9 +183,9 @@ pub(crate) fn print_where_clause( let clause = if f.alternate() { if ending == Ending::Newline { - format!(" where{where_preds},") + format!(" where{where_preds:#},") } else { - format!(" where{where_preds}") + format!(" where{where_preds:#}") } } else { let mut br_with_padding = String::with_capacity(6 * indent + 28); diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 336513804e1ff..49a8c077188dd 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -2324,17 +2324,15 @@ where #[derive(PartialEq, Eq)] struct ImplString { - rendered: String, - is_negative: bool, + // Plain text (not HTML text) because this is only used for sorting purposes, and the plain + // text is much shorter and thus faster to compare. + cmp_text: String, } impl ImplString { fn new(i: &Impl, cx: &Context<'_>) -> ImplString { let impl_ = i.inner_impl(); - ImplString { - is_negative: impl_.is_negative_trait_impl(), - rendered: format!("{}", print_impl(impl_, false, cx)), - } + ImplString { cmp_text: format!("{:#}", print_impl(impl_, false, cx)) } } } @@ -2346,12 +2344,9 @@ impl PartialOrd for ImplString { impl Ord for ImplString { fn cmp(&self, other: &Self) -> Ordering { - // We sort negative impls first. - match (self.is_negative, other.is_negative) { - (false, true) => Ordering::Greater, - (true, false) => Ordering::Less, - _ => compare_names(&self.rendered, &other.rendered), - } + // Negative impls are naturally sorted first, because `impl !A` is less than `impl B` for + // any value of `B`, because `!` is less than any identifier-starting char. + compare_names(&self.cmp_text, &other.cmp_text) } } diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 26894a64c6c14..c366af8778ed6 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -14,7 +14,6 @@ //! or contains "invocation-specific". use std::cell::RefCell; -use std::cmp::Ordering; use std::ffi::{OsStr, OsString}; use std::fs::File; use std::io::{self, Write as _}; @@ -730,8 +729,10 @@ impl TraitAliasPart { None } else { let impl_ = imp.inner_impl(); + let print = print_impl(impl_, false, cx); Some(Implementor { - text: print_impl(impl_, false, cx).to_string(), + text: format!("{}", print), + cmp_text: format!("{:#}", print), synthetic: imp.inner_impl().kind.is_auto(), types: collect_paths_for_type(&imp.inner_impl().for_, cache), is_negative: impl_.is_negative_trait_impl(), @@ -754,14 +755,9 @@ impl TraitAliasPart { path.push(format!("{remote_item_type}.{}.js", remote_path[remote_path.len() - 1])); let mut implementors = implementors.collect::>(); - implementors.sort_unstable_by(|a, b| { - // We sort negative impls first. - match (a.is_negative, b.is_negative) { - (false, true) => Ordering::Greater, - (true, false) => Ordering::Less, - _ => compare_names(&a.text, &b.text), - } - }); + // Negative impls are naturally sorted first, because `impl !A` is less than `impl B` + // for any value of `B`, because `!` is less than any identifier-starting char. + implementors.sort_unstable_by(|a, b| compare_names(&a.cmp_text, &b.cmp_text)); let part = OrderedJson::array_unsorted( implementors @@ -777,7 +773,11 @@ impl TraitAliasPart { } struct Implementor { + // HTML text used in generated output. text: String, + // Plain text used just for sorting output. This is a performance win, because this plain text + // is much shorter than the HTML output and sorting is hot. + cmp_text: String, synthetic: bool, types: Vec, is_negative: bool,