human-sort
human-sort copied to clipboard
Panics with Rust 1.81 sort implementation
The following code panics on Rust 1.81:
fn main() {
let mut x = [
"data_0_1_0.csv.zst",
"data_12_1_0.csv.zst",
"data_2_2_0.csv.zst",
"data_4_1_0.csv.zst",
"data_6_3_0.csv.zst",
"data_9_1_0.csv.zst",
"data_10_2_0.csv.zst",
"data_12_2_0.csv.zst",
"data_3_0_0.csv.zst",
"data_4_2_0.csv.zst",
"data_7_0_0.csv.zst",
"data_11_0_0.csv.zst",
"data_13_2_0.csv.zst",
"data_3_1_0.csv.zst",
"data_4_3_0.csv.zst",
"data_8_0_0.csv.zst",
"data_1_2_0.csv.zst",
"data_13_3_0.csv.zst",
"data_4_0_0.csv.zst",
"data_5_0_0.csv.zst",
"data_8_3_0.csv.zst",
];
x.sort_by(|p1, p2| human_sort::compare(p1, p2));
}
Panic message is:
thread 'main' panicked at library/core/src/slice/sort/shared/smallsort.rs:862:5:
user-provided comparison function does not correctly implement a total order
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Since the comparison function is taken verbatim from human_sort, this is a bug in human_sort::compare(). To debug it, we can log the comparisons, i.e.:
fn main() {
... as before ...
x.sort_by(|p1, p2| compare_and_log(p1, p2));
}
fn compare_and_log(s1: &str, s2: &str) -> Ordering {
let result = human_sort::compare(s1, s2);
println!("cmp({s1:?}, {s2:?}) == {result:?}");
result
}
I didn't study which comparisons failed the total order check, but I noticed two (out of 38) comparisons to be obviously wrong, and might well be the ones causing the issue:
cmp("data_13_3_0.csv.zst", "data_1_2_0.csv.zst") == Less
cmp("data_1_2_0.csv.zst", "data_13_3_0.csv.zst") == Greater
For anyone finding this via google, this crate appears unmaintained (see #1, #2, and #3). I resolved the issue by switching to numeric-sort.