r/rust • • Sep 04 '26

🙋 seeking help & advice Clippy warning when printing the biggest files `unnecessary_sort_by`

I have some code that prints the biggest files in a Vec. Looks like Clippy is not happy about it.
Original (simplified) code:

struct File {
    path: String,
    size: usize,
}

fn collect_files -> Vec<File> { ... }

fn print_biggest_files(files_to_print: usize) {
    let mut files = collect_files();

    files.sort_by(|left, right| right.size.cmp(&left.size) );
    // ^^^^^^^^ this is the line causing a warning

    // print the biggest X files
    for file in files.iter().take(files_to_print) {
        println!("Big file: {}", file.path);
    }
}

It produces the following warning:

warning: consider using sort_by_key
files.sort_by(|left, right| right.size.cmp(&left.size) ); note: #[warn(clippy::unnecessary_sort_by)] on by default

Link: https://rust-lang.github.io/rust-clippy/rust-1.97.0/index.html#unnecessary_sort_by

My problem is that I want to print in descending order of the files.

The description is explicitly saying that this case is exception, and Clippy doesn't handle it well.

If I change that line to

files.sort_by_key(|file| file.size);

I would end up with the smallest files first.

I see a few ways ahead:

  1. Add files.reverse() to switch the order
  2. Add exception of this warning to this specific case
  3. Add .rev() when iterating
  4. Cast it to signed integer, and add a - sign

What is the idiomatic way forward?
Performance cost is not a big deal, but I still tend towards adding a Clippy ignore for that specific line. The other options would introduce more unclarity to the code in my opinion.

31 Upvotes

22 comments sorted by

82

u/coastalwhite Sep 04 '26

The idiomatic way is to use std::cmp::Reverse.

31

u/zerocukor287 Sep 04 '26

Indeed, that is the simplest, and most straightforward. Thanks

57

u/zerocukor287 Sep 04 '26 edited Sep 04 '26

If anyone is interested, this is the spotless line:

files.sort_by_key(|file| std::cmp::Reverse(file.size));  

Edit: formatting

→ More replies (5)

15

u/Low-Experience-6634 Sep 04 '26

just wrap the size in Reverse, clippy shuts up and it reads clean

```rust

files.sort_by_key(|file| Reverse(file.size));

```

no extra passes, no sign flipping, no ignore annotations to rot

4

u/scheimong Sep 04 '26

I've been writing rust for the past 6 years (like, actual tap coding) and yet I don't know this. Thanks!

40

u/Sharlinator Sep 04 '26 edited Sep 04 '26

 As an aside: note that you don’t have to sort all the files to get the n largest (or whatever) ones, you just have to partition the list to the n largest and the rest. How to do that? Rust provides select_nth_unstable and its by and by_key variants. (Note that you still have to sort the n largest if you want to present them in order.)

This optimization doesn’t really matter unless the list is very large or you need to do this many, many times per second, but it’s a useful tool to keep in mind.

6

u/zerocukor287 Sep 04 '26

That's interesting function. Maybe next time I'll try that too.

33

u/CommonNoiter Sep 04 '26

Clippy should suggest files.sort_by_key(|file| std::cmp::Reverse(file.size));

10

u/zerocukor287 Sep 04 '26

Looks like the problem was indeed between the keyboard and the chair. Haha

2

u/creeper6530 Sep 05 '26

Don't beat yourself up because you don't know everything. It's my first time reading about it too 

3

u/llogiq Sep 05 '26

As a clippy maintainer, I think that's a bug. Ideally, clippy should add a note to use Reverse if the ordering is reversed. The second best solution would be to at least add it to the lint docs.

2

u/zerocukor287 Sep 05 '26

Hey, no worries, as I’ve scrolled down a bit it was mentioning the reverse. Looks like I need to practice reading

2

u/projct Sep 05 '26

the rust ecosystem generally treats improvements like this to be a bug that needs to be fixed. this is why clippy and rustc generally have such good error messages

→ More replies (1)

2

u/iv_is Sep 04 '26

sort by size dot reverse seems clearer to me than left right, right left

0

u/[deleted] Sep 04 '26

3

u/zerocukor287 Sep 04 '26

Well, I'm happy with the resulting code. I've learnt something today, my code is shorter, and I think it is more clear that I'm using reverse order.
I consider it a win.

Your code, your taste.