Skip to content

Conversation

@tisonkun
Copy link
Contributor

@tisonkun tisonkun commented Nov 25, 2025

This refers to #149046.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Nov 25, 2025
@rustbot
Copy link
Collaborator

rustbot commented Nov 25, 2025

r? @scottmcm

rustbot has assigned @scottmcm.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@tisonkun tisonkun force-pushed the slice_partial_sort_unstable branch from 115ac5c to 0e87d5d Compare November 25, 2025 16:42
@tisonkun
Copy link
Contributor Author

cc @orlp

Copy link
Contributor

@orlp orlp left a comment

Choose a reason for hiding this comment

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

Left some remarks, some on style, but also some with substance.

Besides comments on the code that's written, I do note a lack of tests?

View changes since this review

@tisonkun
Copy link
Contributor Author

I do note a lack of tests?

Doc tests cover most branches. I don't find a dedicated file to cover its cousin sort_unstable. If you can point me to one, I'm glad to add cases there.

@orlp
Copy link
Contributor

orlp commented Nov 26, 2025

The examples can change at any time. And you didn't test, for example, the post-condition that all elements ..start are less than or equal to the elements start..end and that those are less than or equal to the elements end.., including for the zero-length case.

@tisonkun
Copy link
Contributor Author

The examples can change at any time. And you didn't test, for example, the post-condition that all elements ..start are less than or equal to the elements start..end and that those are less than or equal to the elements end.., including for the zero-length case.

Thanks and yes. Do you know where the unit tests of sort/sort_unstable locate?

@orlp
Copy link
Contributor

orlp commented Nov 26, 2025

I believe the bulk is found in https://github.com/rust-lang/rust/blob/main/library/alloctests/tests/sort/tests.rs.

@orlp
Copy link
Contributor

orlp commented Nov 26, 2025

What I suggested in the ACP was a sketch implementation, I did some more thinking and I think the following handles all corner cases nicely:

pub fn partial_sort<T, F, R>(mut v: &mut [T], range: R, is_less: &mut F)
where
    F: FnMut(&T, &T) -> bool,
    R: RangeBounds<usize>,
{
    let len = v.len();
    let Range { start, end } = slice::range(range, ..len);
    
    if end - start <= 1 {
        // Can be resolved in at most a single partition_at_index call, without
        // further sorting. Do nothing if it is an empty range at start or end.
        if start != len && end != 0 {
            sort::select::partition_at_index(v, start, is_less);
        }
        return;
    }
    
    // Don't bother reducing the slice to sort if it eliminates fewer than 8 elements.
    if end + 8 <= len {
        v = sort::select::partition_at_index(v, end - 1, is_less).0;
    }
    if start >= 8 {
        v = sort::select::partition_at_index(v, start, is_less).2;
    }
    sort::unstable::sort(v, is_less);
}

And to formalize the post-conditions, I think the following should hold after a call to v.partial_sort_unstable(b..e):

for i in 0..b {
    for j in b..n {
        assert!(v[i] <= v[j]);
    }
}
for i in 0..e {
    for j in e..n {
        assert!(v[i] <= v[j]);
    }
}
for i in b..e {
    for j in i..e {
        assert!(v[i] <= v[j]);
    }
}

@quaternic
Copy link
Contributor

quaternic commented Nov 28, 2025

And to formalize the post-conditions, I think the following should hold after a call to v.partial_sort_unstable(b..e):

A lot of those individual comparisons are implied by transitivity of the ordering, so it can be reduced to choosing the maximum of the prefix (if any), the minimum of the suffix (if any), and then asserting that the concatenation is sorted.

Informally, max(v[..b]) <= v[b] <= v[b + 1] <= ... <= v[e-1] <= min(v[e..]), or in code:

let max_before = v[..b].iter().max().into_iter();
let sorted_range = v[b..e].iter();
let min_after = v[e..].iter().min().into_iter();
let seq = max_before.chain(sorted_range).chain(min_after);
assert!(seq.is_sorted());

That's pretty much what you said in rust-lang/libs-team#685 (comment) , just using transitivity of the comparison. Without assuming that, the implementation couldn't guarantee the universally quantified property anyway.

@tisonkun tisonkun force-pushed the slice_partial_sort_unstable branch from f9a09e0 to 372589e Compare December 1, 2025 04:09
@rustbot

This comment has been minimized.

@tisonkun
Copy link
Contributor Author

tisonkun commented Dec 1, 2025

Pushed a new implementation.

I'm writing tests but perhaps we'd have a new mod under library/alloctests/tests/partial_sort rather than patch the existing library/alloctests/tests/sort/tests.rs. Since the sort tests are heavily depending on macros while partial sorts assertions are quite different.

@tisonkun
Copy link
Contributor Author

tisonkun commented Dec 1, 2025

Pushed a new implementation.

I'm writing tests but perhaps we'd have a new mod under library/alloctests/tests/partial_sort rather than patch the existing library/alloctests/tests/sort/tests.rs. Since the sort tests are heavily depending on macros while partial sorts assertions are quite different.

cc @Amanieu for early review for the direction and advice on where to organize the tests.

@rust-log-analyzer

This comment has been minimized.

@tisonkun tisonkun force-pushed the slice_partial_sort_unstable branch 2 times, most recently from 6ef6ab4 to 10d053f Compare December 1, 2025 10:57
@rust-log-analyzer

This comment has been minimized.

@tisonkun tisonkun force-pushed the slice_partial_sort_unstable branch from 10d053f to 43fc006 Compare December 1, 2025 11:13
@rust-bors rust-bors bot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 9, 2026
@rust-bors
Copy link
Contributor

rust-bors bot commented Jan 9, 2026

📌 Commit 45e0fbf has been approved by tgross35

It is now in the queue for this repository.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jan 9, 2026
…oss35

Implement partial_sort_unstable for slice

This refers to rust-lang#149046.
@matthiaskrgr
Copy link
Member

@bors r-
I suspect this caused the c_str test failures here
#150856 (comment)

@rust-bors rust-bors bot added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jan 9, 2026
@rust-bors
Copy link
Contributor

rust-bors bot commented Jan 9, 2026

Commit 45e0fbf has been unapproved.

@rust-bors rust-bors bot removed the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Jan 9, 2026
@tisonkun
Copy link
Contributor Author

tisonkun commented Jan 9, 2026

@bors r- I suspect this caused the c_str test failures here #150856 (comment)

Do you have a more concrete analysis? This PR adds new code that should not be used anywhere else so far.

@matthiaskrgr
Copy link
Member

not really, besides "the test no longer failed when I excluded it from the rollup" unfortunately

@matthiaskrgr
Copy link
Member

@bors try jobs=aarch64-gnu-llvm-20-1

@rust-bors

This comment has been minimized.

rust-bors bot added a commit that referenced this pull request Jan 9, 2026
Implement partial_sort_unstable for slice

try-job: aarch64-gnu-llvm-20-1
@tgross35
Copy link
Contributor

tgross35 commented Jan 9, 2026

I don't think there's any reason this should have caused a failure there, it's completely unrelated. What a bizarre issue though, which test actually failed? It didn't print that info so it's like the test runner itself crashed.

@tgross35
Copy link
Contributor

tgross35 commented Jan 9, 2026

...well, one of the PRs in that rollup actually did change the test runner #150131. I'll start a job there to check

@rust-bors
Copy link
Contributor

rust-bors bot commented Jan 9, 2026

☀️ Try build successful (CI)
Build commit: ee91d0f (ee91d0f40ecff4a1edc29fa3385ebc462e9bdce0, parent: 3fda0e426ca17b0baa0d6e765a0d23f487350573)

@tgross35
Copy link
Contributor

tgross35 commented Jan 9, 2026

Huh, neither this one nor that one then. That's a scary issue to have if it's spurious...

@bors r+

@rust-bors rust-bors bot added the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Jan 9, 2026
@rust-bors
Copy link
Contributor

rust-bors bot commented Jan 9, 2026

📌 Commit 45e0fbf has been approved by tgross35

It is now in the queue for this repository.

@rust-bors rust-bors bot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jan 9, 2026
tgross35 added a commit to tgross35/rust that referenced this pull request Jan 9, 2026
…oss35

Implement partial_sort_unstable for slice

This refers to rust-lang#149046.
rust-bors bot added a commit that referenced this pull request Jan 10, 2026
Rollup of 9 pull requests

Successful merges:

 - #149318 (Implement partial_sort_unstable for slice)
 - #150805 (Fix ICE in inline always warning emission.)
 - #150822 (Fix for ICE: eii: fn / macro rules None in find_attr())
 - #150853 (std: sys: fs: uefi: Implement File::read)
 - #150855 (std: sys: fs: uefi: Implement File::tell)
 - #150881 (Fix std::fs::copy on WASI by setting proper OpenOptions flags)
 - #150891 (Fix a trivial typo in def_id.rs)
 - #150892 (Don't check `[mentions]` paths in submodules from tidy)
 - #150894 (cg_llvm: add a pause to make comment less confusing)

r? @ghost
@rust-bors rust-bors bot merged commit 65c0847 into rust-lang:main Jan 10, 2026
12 checks passed
@rustbot rustbot added this to the 1.94.0 milestone Jan 10, 2026
rust-timer added a commit that referenced this pull request Jan 10, 2026
Rollup merge of #149318 - slice_partial_sort_unstable, r=tgross35

Implement partial_sort_unstable for slice

This refers to #149046.
@tisonkun tisonkun deleted the slice_partial_sort_unstable branch January 10, 2026 05:09
@Zalathar
Copy link
Member

It looks like the newly-added tests in alloctests are taking an additional 1.5 hours to run under Miri (!), which has exploded CI times to 4 hours.

I have a proposed fix at #150947.

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-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants