Skip to content

Conversation

@ebroto
Copy link
Contributor

@ebroto ebroto commented Sep 4, 2020

Vec::sort_by_key closure parameter is F: FnMut(&T) -> K. The lint's suggestion destructures the T parameter; this was probably done to avoid different unnamed lifetimes when K = Reverse<&T>.

This change fixes two issues:

  • Destructuring T when T is non-reference requires the type to be Copy, otherwise we would try to move from a shared reference. We make sure T: Copy holds.
  • Make sure T is actually non-reference. I didn't go for destructuring multiple levels of references, as we would have to compensate in the closure body by removing derefs and maybe adding parens, which would add more complexity.

changelog: Restrict [unnecessary_sort_by] to non-reference, Copy types

Fixes #6001

@rust-highfive
Copy link

r? @Manishearth

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Sep 4, 2020
@Manishearth
Copy link
Member

@bors r+

@bors
Copy link
Contributor

bors commented Sep 6, 2020

📌 Commit 9950092 has been approved by Manishearth

@bors
Copy link
Contributor

bors commented Sep 6, 2020

⌛ Testing commit 9950092 with merge 5720dd3...

bors added a commit that referenced this pull request Sep 6, 2020
Restrict unnecessary_sort_by to non-reference, Copy types

`Vec::sort_by_key` closure parameter is `F: FnMut(&T) -> K`. The lint's suggestion destructures the `T` parameter; this was probably done to avoid different unnamed lifetimes when `K = Reverse<&T>`.

This change fixes two issues:
* Destructuring T when T is non-reference requires the type to be Copy, otherwise we would try to move from a shared reference. We make sure `T: Copy` holds.
* Make sure `T` is actually non-reference. I didn't go for destructuring multiple levels of references, as we would have to compensate in the closure body by removing derefs and maybe adding parens, which would add more complexity.

changelog: Restrict [`unnecessary_sort_by`] to non-reference, Copy types

Fixes #6001
@bors
Copy link
Contributor

bors commented Sep 6, 2020

💔 Test failed - checks-action_test

@ebroto ebroto force-pushed the 6001_unnecessary_sort_by branch from 9950092 to b22f50e Compare September 6, 2020 22:13
@ebroto ebroto force-pushed the 6001_unnecessary_sort_by branch from b22f50e to 9fa9208 Compare September 6, 2020 22:19
@ebroto
Copy link
Contributor Author

ebroto commented Sep 6, 2020

@bors r=Manishearth

@bors
Copy link
Contributor

bors commented Sep 6, 2020

📌 Commit 9fa9208 has been approved by Manishearth

@bors
Copy link
Contributor

bors commented Sep 6, 2020

⌛ Testing commit 9fa9208 with merge daad592...

@bors
Copy link
Contributor

bors commented Sep 6, 2020

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: Manishearth
Pushing daad592 to master...

@bors bors merged commit daad592 into rust-lang:master Sep 6, 2020
@ebroto ebroto deleted the 6001_unnecessary_sort_by branch September 6, 2020 22:58
bors added a commit that referenced this pull request Oct 6, 2020
unnecessary sort by: avoid dereferencing the suggested closure parameter

This change tries to simplify the solution for problematic cases but is less restrictive than  #6006.

* We can't dereference shared references to non-Copy types, so the new suggestion does not do that. Note that this implies that the suggested closure parameter will be a reference.
* We can't take a reference to the closure parameter in the returned key, so we don't lint in those cases. This can happen either because the key borrows from the parameter (e.g. `|a| a.borrows()`), or because we suggest `|a| Reverse(a)`. If we did we would hit this error:
```
error: lifetime may not live long enough
  --> /home/ebroto/src/ebroto-clippy/tests/ui/unnecessary_sort_by.fixed:19:25
   |
19 |     vec.sort_by_key(|b| Reverse(b));
   |                      -- ^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
   |                      ||
   |                      |return type of closure is Reverse<&'2 isize>
   |                      has type `&'1 isize`

error: aborting due to previous error
```

Note that Clippy does not currently have the (MIR-based) machinery necessary to check that what is borrowed is actually the closure parameter.

changelog: [`unnecessary_sort_by`]: avoid dereferencing the suggested closure parameter

Fixes #6001
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect suggestion in "unnecessary-sort-by"

4 participants