Skip to content

unnecessary_sort_by false positive on shared reference keys #5976

Closed
@tdyas

Description

@tdyas

The unnecessary_sort_by lint is a false positive when it suggests to use sort_by_key for keys that are shared references. The key cannot be returned in that case as it will not survive long enough.

See this PR to the Pants project for an example.

Clippy triggers on this code:

$ cargo clippy
    Checking fs v0.0.1 (XXX/pants/src/rust/engine/fs)
error: use Vec::sort_by_key here instead
   --> fs/src/glob_matching.rs:539:5
    |
539 |     path_stats.sort_by(|a, b| a.path().cmp(b.path()));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `path_stats.sort_by_key(|&a| a.path())`
    |
note: the lint level is defined here
   --> fs/src/lib.rs:7:3
    |
7   |   clippy::all,
    |   ^^^^^^^^^^^
    = note: `#[deny(clippy::unnecessary_sort_by)]` implied by `#[deny(clippy::all)]`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_sort_by

error: aborting due to previous error

error: could not compile `fs`.

To learn more, run the command again with --verbose.

Following Clippy's suggestion results in:

$ cargo clippy
    Checking fs v0.0.1 (XXX/pants/src/rust/engine/fs)
error[E0507]: cannot move out of a shared reference
   --> fs/src/glob_matching.rs:539:29
    |
539 |     path_stats.sort_by_key(|&a| a.path());
    |                             ^-
    |                             ||
    |                             |data moved here
    |                             |move occurs because `a` has type `PathStat`, which does not implement the `Copy` trait
    |                             help: consider removing the `&`: `a`

error[E0515]: cannot return value referencing local variable `a`
   --> fs/src/glob_matching.rs:539:33
    |
539 |     path_stats.sort_by_key(|&a| a.path());
    |                                 -^^^^^^^
    |                                 |
    |                                 returns a value referencing data owned by the current function
    |                                 `a` is borrowed here

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0507, E0515.
For more information about an error, try `rustc --explain E0507`.
error: could not compile `fs`.

To learn more, run the command again with --verbose.

Following the next suggestion to remove the & marker results in:

$ cargo clippy
    Checking fs v0.0.1 (XXX/pants/src/rust/engine/fs)
error: lifetime may not live long enough
   --> fs/src/glob_matching.rs:539:32
    |
539 |     path_stats.sort_by_key(|a| a.path());
    |                             -- ^^^^^^^^ returning this value requires that `'1` must outlive `'2`
    |                             ||
    |                             |return type of closure is &'2 std::path::Path
    |                             has type `&'1 PathStat`

error: aborting due to previous error

error: could not compile `fs`.

To learn more, run the command again with --verbose.

Meta

  • cargo clippy -V: clippy 0.0.212 (04488afe3 2020-08-24)
  • rustc -Vv:
rustc 1.46.0 (04488afe3 2020-08-24)
binary: rustc
commit-hash: 04488afe34512aa4c33566eb16d8c912a3ae04f9
commit-date: 2020-08-24
host: x86_64-apple-darwin
release: 1.46.0
LLVM version: 10.0 

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thingI-suggestion-causes-errorIssue: The suggestions provided by this Lint cause an ICE/error when applied

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions