Skip to content

Add customized compare for Link in rustdoc #137106

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 20, 2025

Conversation

chenyukang
Copy link
Member

@chenyukang chenyukang commented Feb 16, 2025

Maybe some other types in sidebar need to be sorted in this way, maybe add this crate natord is ok?

r? clubby789

Fixes #137098

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. labels Feb 16, 2025
@rustbot
Copy link
Collaborator

rustbot commented Feb 16, 2025

These commits modify the Cargo.lock file. Unintentional changes to Cargo.lock can be introduced when switching branches and rebasing PRs.

If this was unintentional then you should revert the changes before this PR is merged.
Otherwise, you can ignore this comment.

@@ -7,10 +7,12 @@
//@ has - '//h2[@id="foreign-impls"]' 'Implementations on Foreign Types'
//@ has - '//*[@class="sidebar-elems"]//section//a[@href="#impl-Foo-for-u32"]' 'u32'
//@ has - '//*[@id="impl-Foo-for-u32"]//h3[@class="code-header"]' 'impl Foo for u32'
//@ has - '//*[@id="impl-Foo-for-u8"]//h3[@class="code-header"]' 'impl Foo for u8'
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how to assert u8 and u32 is in a sorted way ...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can check if it's the nth item of this type, but not sure we can outdide gui tests...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just added new ui testcase:

tests/rustdoc/sidebar-link-sort.rs and tests/rustdoc/sidebar-link-sort.sidebar.html

@fmease
Copy link
Member

fmease commented Feb 16, 2025

r? rustdoc

@rustbot rustbot assigned GuillaumeGomez and unassigned clubby789 Feb 16, 2025
@GuillaumeGomez
Copy link
Member

Do you have a before/after screenshot?

@chenyukang
Copy link
Member Author

Before:
image

After:
image

@chenyukang chenyukang force-pushed the yukang-fix-sidebar-sort branch 2 times, most recently from 944d61f to c7cb559 Compare February 16, 2025 12:25
pub trait Foo {}

//@ has 'foo/trait.Foo.html'
//@ snapshot sidebar - '//*[@class="sidebar-elems"]'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sadly doesn't enforce really well the sorting order here since a --bless will just update the html file.

Copy link
Member Author

@chenyukang chenyukang Feb 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't get you point, we treat the HTML files as compared files just like stderr file in other unit testing, we can see the names and links in HTML file (tests/rustdoc/sidebar-link-sort.sidebar.html) are sorted as assumed, if anything broke the sorting order, the HTML files will be changed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mentioned that it should likely be a gui test (tests/rustdoc-gui) here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added test case in tests/rustdoc-gui.

@GuillaumeGomez
Copy link
Member

@notriddle Didn't we do something like this already? I remember something you did on "naturally" sorting items some time ago.

@notriddle
Copy link
Contributor

@GuillaumeGomez Yes, we do. It's called rustdoc::html::render::print_item::compare_names.

@chenyukang Please use that instead of pulling in a second implementation.

@chenyukang chenyukang force-pushed the yukang-fix-sidebar-sort branch from c7cb559 to b711a2a Compare February 18, 2025 01:40
@rustbot
Copy link
Collaborator

rustbot commented Feb 18, 2025

Some changes occurred in GUI tests.

cc @GuillaumeGomez

@chenyukang chenyukang force-pushed the yukang-fix-sidebar-sort branch from b711a2a to 4ba3796 Compare February 18, 2025 01:42
@chenyukang
Copy link
Member Author

chenyukang commented Feb 18, 2025

When I run all the tests in tests/rustdoc-gui with command on my dev machine:

./x.py test tests/rustdoc-gui --stage 1

There are some failed with errors, I verified it's not related to my new added test case:

rust git:(yukang-fix-sidebar-sort) ./x.py test tests/rustdoc-gui --stage 1
Building bootstrap
    Finished `dev` profile [unoptimized] target(s) in 0.11s
Building stage0 library artifacts (aarch64-apple-darwin)
    Finished `release` profile [optimized + debuginfo] target(s) in 0.04s
Building compiler artifacts (stage0 -> stage1, aarch64-apple-darwin)
    Finished `release` profile [optimized + debuginfo] target(s) in 0.44s
Creating a sysroot for stage1 compiler (use `rustup toolchain link 'name' build/host/stage1`)
Building stage1 library artifacts (aarch64-apple-darwin)
    Finished `release` profile [optimized + debuginfo] target(s) in 0.05s
Building stage0 tool rustdoc-gui-test (aarch64-apple-darwin)
    Finished `release` profile [optimized + debuginfo] target(s) in 0.17s
Building tool rustdoc (stage0 -> stage1, aarch64-apple-darwin)
   Compiling rustdoc v0.0.0 (/Users/yukang/rust/src/librustdoc)
   Compiling rustdoc-tool v0.0.0 (/Users/yukang/rust/src/tools/rustdoc)
    Finished `release` profile [optimized + debuginfo] target(s) in 16.41s
Testing rustdoc-gui (stage1 -> stage2, aarch64-apple-darwin)
 Documenting settings v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/settings)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.88s
   Generated /Users/yukang/rust/build/aarch64-apple-darwin/test/rustdoc-gui/doc/settings/index.html
    Checking http v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/lib2/http)
 Documenting http v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/lib2/http)
    Checking implementors v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/lib2/implementors)
 Documenting implementors v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/lib2/implementors)
 Documenting lib2 v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/lib2)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.39s
   Generated /Users/yukang/rust/build/aarch64-apple-darwin/test/rustdoc-gui/doc/lib2/index.html
 Documenting link_to_definition v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/link_to_definition)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.44s
   Generated /Users/yukang/rust/build/aarch64-apple-darwin/test/rustdoc-gui/doc/link_to_definition/index.html
 Documenting huge_logo v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/huge_logo)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.43s
   Generated /Users/yukang/rust/build/aarch64-apple-darwin/test/rustdoc-gui/doc/huge_logo/index.html
    Checking scrape_examples v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/scrape_examples)
    Scraping scrape_examples v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/scrape_examples)
 Documenting scrape_examples v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/scrape_examples)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.33s
   Generated /Users/yukang/rust/build/aarch64-apple-darwin/test/rustdoc-gui/doc/scrape_examples/index.html
 Documenting proc_macro_test v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/proc_macro_test)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.62s
   Generated /Users/yukang/rust/build/aarch64-apple-darwin/test/rustdoc-gui/doc/proc_macro_test/index.html
 Documenting staged_api v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/staged_api)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.44s
   Generated /Users/yukang/rust/build/aarch64-apple-darwin/test/rustdoc-gui/doc/staged_api/index.html
 Documenting extend_css v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/extend_css)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.53s
   Generated /Users/yukang/rust/build/aarch64-apple-darwin/test/rustdoc-gui/doc/extend_css/index.html
 Documenting theme_css v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/theme_css)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.42s
   Generated /Users/yukang/rust/build/aarch64-apple-darwin/test/rustdoc-gui/doc/theme_css/index.html
   Compiling test_docs v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/test_docs)
 Documenting test_docs v0.1.0 (/Users/yukang/rust/tests/rustdoc-gui/src/test_docs)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.92s
   Generated /Users/yukang/rust/build/aarch64-apple-darwin/test/rustdoc-gui/doc/test_docs/index.html
Running 135 rustdoc-gui (10 concurrently) ...
.......... (10/135)
.......... (20/135)
.......... (30/135)
.......... (40/135)
.......... (50/135)
.......... (60/135)
.......... (70/135)
.......... (80/135)
.......... (90/135)
.......... (100/135)
.......... (110/135)
.......... (120/135)
.......... (130/135)
FFFFF      (135/135)


/Users/yukang/rust/tests/rustdoc-gui/item-info.goml item-info... FAILED
[ERROR] `tests/rustdoc-gui/item-info.goml` line 23: Condition `|first_line_y| != |second_line_y| && |first_line_y| == 718 && |second_line_y| == 741` (`718 != 742 && 718 == 718 && 742 == 741`) was evaluated as false: for command `assert: |first_line_y| != |second_line_y| && |first_line_y| == 718 && |second_line_y| == 741`

/Users/yukang/rust/tests/rustdoc-gui/search-filter.goml search-filter... FAILED
[ERROR] `tests/rustdoc-gui/search-filter.goml` line 24: The following errors happened: [document property `URL` (`file:///Users/yukang/rust/build/aarch64-apple-darwin/test/rustdoc-gui/doc/test_docs/index.html?search=test`) doesn't contain `&filter-crate=` (for CONTAINS check)]: for command `assert-document-property: ({"URL": "&filter-crate="}, CONTAINS)`
[ERROR] `tests/rustdoc-gui/search-filter.goml` line 26: assert didn't fail: for command `assert-false: "#results .externcrate"`
[ERROR] `tests/rustdoc-gui/search-filter.goml` line 28: The following errors happened (for selector `#crate-search`): [expected `lib2` for property `"value"`, found `all crates`]: for command `assert-property: ("#crate-search", {"value": "lib2"})`
[ERROR] `tests/rustdoc-gui/search-filter.goml` line 37: assert didn't fail: for command `assert-false: "#results .externcrate"`
[ERROR] `tests/rustdoc-gui/search-filter.goml` line 38: The following errors happened (for selector `#crate-search`): [expected `lib2` for property `"value"`, found `all crates`]: for command `assert-property: ("#crate-search", {"value": "lib2"})`

/Users/yukang/rust/tests/rustdoc-gui/search-result-display.goml search-result-display... FAILED
[WARNING] `tests/rustdoc-gui/search-result-display.goml` line 37: Delta is 0 for "x", maybe try to use `compare-elements-position` instead?

[ERROR] `tests/rustdoc-gui/search-result-display.goml` line 53: The following errors happened (for selector `#crate-search`): [expected `159px` for key `width`, found `158.5px`]: for command `assert-css: ("#crate-search", {"width": "159px"})`

/Users/yukang/rust/tests/rustdoc-gui/sidebar-mobile.goml sidebar-mobile... FAILED
[ERROR] `tests/rustdoc-gui/sidebar-mobile.goml` line 52: The following errors happened: [different Y values: 45 (or 45) != 46]: for command `assert-position: ("#method\.must_use", {"y": 46})`

/Users/yukang/rust/tests/rustdoc-gui/sidebar-source-code-display.goml sidebar-source-code-display... FAILED
[ERROR] `tests/rustdoc-gui/sidebar-source-code-display.goml` line 145: The following errors happened: [expected `2578` for window property `pageYOffset`, found `2578.5`]: for command `assert-window-property: {"pageYOffset": |y_offset|}`
[ERROR] `tests/rustdoc-gui/sidebar-source-code-display.goml` line 152: The following errors happened: [expected `2578` for window property `pageYOffset`, found `2578.5`]: for command `assert-window-property: {"pageYOffset": |y_offset|}`

Error: ()
Build completed unsuccessfully in 0:01:26

Is it because of my own browser settings, I don't know.

@rust-log-analyzer

This comment has been minimized.

@chenyukang chenyukang force-pushed the yukang-fix-sidebar-sort branch 2 times, most recently from 9981683 to 3fc3bcc Compare February 18, 2025 03:02
@@ -297,7 +298,7 @@ fn sidebar_trait<'a>(
.filter_map(|i| super::extract_for_impl_name(&i.impl_item, cx))
.map(|(name, id)| Link::new(id, name)),
);
foreign_impls.sort();
foreign_impls.sort_by(|a, b| compare_names(&a.name, &b.name));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't like this particular implementation. There's two problems with it:

  1. There's no actual rule against having two sidebar items with the same name. I'd like to make sure they get sorted stably.
  2. As you mentioned, this only applies to foreign impls. It would be better to sort everything (except Sections, but those are already done correctly).

Instead, we can actually change the PartialOrd implementation for Link, and, that way, continue sorting everything the same way except for names:

diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs
index 2675eb3025a..7181751ae26 100644
--- a/src/librustdoc/html/render/sidebar.rs
+++ b/src/librustdoc/html/render/sidebar.rs
@@ -1,4 +1,5 @@
 use std::borrow::Cow;
+use std::cmp::{Ordering, PartialOrd};
 
 use rinja::Template;
 use rustc_data_structures::fx::FxHashSet;
@@ -78,7 +79,7 @@ pub fn should_render(&self) -> bool {
 }
 
 /// A link to an item. Content should not be escaped.
-#[derive(PartialOrd, Ord, PartialEq, Eq, Hash, Clone)]
+#[derive(Ord, PartialEq, Eq, Hash, Clone)]
 pub(crate) struct Link<'a> {
     /// The content for the anchor tag and title attr
     name: Cow<'a, str>,
@@ -90,6 +91,20 @@ pub(crate) struct Link<'a> {
     children: Vec<Link<'a>>,
 }
 
+impl PartialOrd for Link<'_> {
+    fn partial_cmp(&self, other: &Link<'_>) -> Option<Ordering> {
+        match compare_names(&self.name, &other.name) {
+            Ordering::Equal => (),
+            result => return Some(result),
+        }
+        (&self.name_html, &self.href, &self.children).partial_cmp(&(
+            &other.name_html,
+            &other.href,
+            &other.children,
+        ))
+    }
+}
+
 impl<'a> Link<'a> {
     pub fn new(href: impl Into<Cow<'a, str>>, name: impl Into<Cow<'a, str>>) -> Self {
         Self { href: href.into(), name: name.into(), children: vec![], name_html: None }
@@ -298,7 +313,7 @@ fn filter_items<'a>(
                 .filter_map(|i| super::extract_for_impl_name(&i.impl_item, cx))
                 .map(|(name, id)| Link::new(id, name)),
         );
-        foreign_impls.sort_by(|a, b| compare_names(&a.name, &b.name));
+        foreign_impls.sort();
     }
 
     blocks.extend(

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it because of my own browser settings, I don't know.

Yes, it's true. I've tried to run the rustdoc-gui tests on Mac and get similar errors. The gui test here passes when I run it on Linux.

@chenyukang chenyukang force-pushed the yukang-fix-sidebar-sort branch from 3fc3bcc to a467eca Compare February 19, 2025 00:36
@chenyukang chenyukang changed the title Sort sidebar implementations on foreign types with natord::compare Add customized compare for Link in rustdoc Feb 19, 2025
@notriddle
Copy link
Contributor

@bors r+ rollup

@bors
Copy link
Collaborator

bors commented Feb 19, 2025

📌 Commit a467eca has been approved by notriddle

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 19, 2025
bors added a commit to rust-lang-ci/rust that referenced this pull request Feb 20, 2025
…iaskrgr

Rollup of 9 pull requests

Successful merges:

 - rust-lang#135296 (interpret: adjust vtable validity check for higher-ranked types)
 - rust-lang#137106 (Add customized compare for Link in rustdoc)
 - rust-lang#137253 (Restrict `bevy_ecs` `ParamSet` hack)
 - rust-lang#137262 (Make fewer crates depend on `rustc_ast_ir`)
 - rust-lang#137263 (Register `USAGE_OF_TYPE_IR_INHERENT`, remove inherent usages)
 - rust-lang#137266 (MIR visitor tweaks)
 - rust-lang#137269 (Pattern Migration 2024: properly label `&` patterns whose subpatterns are from macro expansions)
 - rust-lang#137277 (stabilize `inherent_str_constructors`)
 - rust-lang#137281 (Tweak "expected ident" parse error to avoid talking about doc comments)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 8ccfd06 into rust-lang:master Feb 20, 2025
6 checks passed
@rustbot rustbot added this to the 1.87.0 milestone Feb 20, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Feb 20, 2025
Rollup merge of rust-lang#137106 - chenyukang:yukang-fix-sidebar-sort, r=notriddle

Add customized compare for Link in rustdoc

Maybe some other types in sidebar need to be sorted in this way, maybe add this crate `natord` is ok?

r?  clubby789

Fixes rust-lang#137098
github-actions bot pushed a commit to tautschnig/verify-rust-std that referenced this pull request Mar 11, 2025
…iaskrgr

Rollup of 9 pull requests

Successful merges:

 - rust-lang#135296 (interpret: adjust vtable validity check for higher-ranked types)
 - rust-lang#137106 (Add customized compare for Link in rustdoc)
 - rust-lang#137253 (Restrict `bevy_ecs` `ParamSet` hack)
 - rust-lang#137262 (Make fewer crates depend on `rustc_ast_ir`)
 - rust-lang#137263 (Register `USAGE_OF_TYPE_IR_INHERENT`, remove inherent usages)
 - rust-lang#137266 (MIR visitor tweaks)
 - rust-lang#137269 (Pattern Migration 2024: properly label `&` patterns whose subpatterns are from macro expansions)
 - rust-lang#137277 (stabilize `inherent_str_constructors`)
 - rust-lang#137281 (Tweak "expected ident" parse error to avoid talking about doc comments)

r? `@ghost`
`@rustbot` modify labels: rollup
github-actions bot pushed a commit to tautschnig/verify-rust-std that referenced this pull request Mar 11, 2025
…iaskrgr

Rollup of 9 pull requests

Successful merges:

 - rust-lang#135296 (interpret: adjust vtable validity check for higher-ranked types)
 - rust-lang#137106 (Add customized compare for Link in rustdoc)
 - rust-lang#137253 (Restrict `bevy_ecs` `ParamSet` hack)
 - rust-lang#137262 (Make fewer crates depend on `rustc_ast_ir`)
 - rust-lang#137263 (Register `USAGE_OF_TYPE_IR_INHERENT`, remove inherent usages)
 - rust-lang#137266 (MIR visitor tweaks)
 - rust-lang#137269 (Pattern Migration 2024: properly label `&` patterns whose subpatterns are from macro expansions)
 - rust-lang#137277 (stabilize `inherent_str_constructors`)
 - rust-lang#137281 (Tweak "expected ident" parse error to avoid talking about doc comments)

r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

"Implementations on foreign types" is sorted in trivial lexographic order in sidebar
8 participants