Skip to content

Nightly clippy: manual_unwrap_or_default false positive #12564

@ilyagr

Description

@ilyagr

Summary

The lint doesn't account for the fact that &Vec is not default; cargo clippy --fix fails

Lint Name

manual_unwrap_or_default

Reproducer

I tried this code:

    pub fn get(&self, id: &CommitId) -> &[RefName] {
        // self.index is of type HashMap<CommitId, Vec<RefName>>
        if let Some(names) = self.index.get(id) {
            names
        } else {
            &[]
        }
   }

Clippy suggests changing it to:

    pub fn get(&self, id: &CommitId) -> &[RefName] {
        // self.index is of type HashMap<CommitId, Vec<RefName>>
        self.index.get(id).unwrap_or_default()
    }

The fix does not compile.

I observed this on running cargo clippy --workspace --all-targets --fix on https://github.com/martinvonz/jj/tree/195e788f921c5840d62afe7c745fcb94b5b9b141.

The error messages: (I omitted some false positives from other clippy bugs, and one true positive)

warning: failed to automatically apply fixes suggested by rustc to crate `jj_cli`

after fixes were automatically applied the compiler reported errors within these files:

  * cli/src/commit_templater.rs

This likely indicates a bug in either rustc or cargo itself,
and we would appreciate a bug report! You're likely to see
a number of compiler warnings after this message which cargo
attempted to fix but failed. If you could open an issue at
https://github.com/rust-lang/rust-clippy/issues
quoting the full output of this command we'd be very appreciative!
Note that you may be able to make some more progress in the near-term
fixing code with the `--broken-code` flag

The following errors were reported:
error[E0277]: the trait bound `&std::vec::Vec<commit_templater::RefName>: std::default::Default` is not satisfied
    --> cli/src/commit_templater.rs:733:28
     |
733  |         self.index.get(id).unwrap_or_default()
     |                            ^^^^^^^^^^^^^^^^^ the trait `std::default::Default` is not implemented for `&std::vec::Vec<commit_templater::RefName>`
     |
     = help: the trait `std::default::Default` is implemented for `std::vec::Vec<T>`
note: required by a bound in `std::option::Option::<T>::unwrap_or_default`
    --> /Users/ilyagr/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:1004:12
     |
1002 |     pub fn unwrap_or_default(self) -> T
     |            ----------------- required by a bound in this associated function
1003 |     where
1004 |         T: Default,
     |            ^^^^^^^ required by this bound in `Option::<T>::unwrap_or_default`
help: consider removing this method call, as the receiver has type `std::collections::HashMap<jj_lib::backend::CommitId, std::vec::Vec<commit_templater::RefName>>` and `std::collections::HashMap<jj_lib::backend::CommitId, std::vec::Vec<commit_templater::RefName>>: std::default::Default` trivially holds
     |
733  -         self.index.get(id).unwrap_or_default()
733  +         self.index.unwrap_or_default()
     |

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
Original diagnostics will follow.

warning: if let can be simplified with `.unwrap_or_default()`
   --> cli/src/commit_templater.rs:733:9
    |
733 | /         if let Some(names) = self.index.get(id) {
734 | |             names
735 | |         } else {
736 | |             &[]
737 | |         }
    | |_________^ help: replace it with: `self.index.get(id).unwrap_or_default()`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_unwrap_or_default
    = note: `#[warn(clippy::manual_unwrap_or_default)]` on by default

warning: `jj-cli` (lib) generated 1 warning (run `cargo clippy --fix --lib -p jj-cli` to apply 1 suggestion)
warning: failed to automatically apply fixes suggested by rustc to crate `jj_cli`

after fixes were automatically applied the compiler reported errors within these files:

  * cli/src/commit_templater.rs

This likely indicates a bug in either rustc or cargo itself,
and we would appreciate a bug report! You're likely to see
a number of compiler warnings after this message which cargo
attempted to fix but failed. If you could open an issue at
https://github.com/rust-lang/rust-clippy/issues
quoting the full output of this command we'd be very appreciative!
Note that you may be able to make some more progress in the near-term
fixing code with the `--broken-code` flag

The following errors were reported:
error[E0277]: the trait bound `&std::vec::Vec<commit_templater::RefName>: std::default::Default` is not satisfied
    --> cli/src/commit_templater.rs:733:28
     |
733  |         self.index.get(id).unwrap_or_default()
     |                            ^^^^^^^^^^^^^^^^^ the trait `std::default::Default` is not implemented for `&std::vec::Vec<commit_templater::RefName>`
     |
     = help: the trait `std::default::Default` is implemented for `std::vec::Vec<T>`
note: required by a bound in `std::option::Option::<T>::unwrap_or_default`
    --> /Users/ilyagr/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:1004:12
     |
1002 |     pub fn unwrap_or_default(self) -> T
     |            ----------------- required by a bound in this associated function
1003 |     where
1004 |         T: Default,
     |            ^^^^^^^ required by this bound in `Option::<T>::unwrap_or_default`
help: consider removing this method call, as the receiver has type `std::collections::HashMap<jj_lib::backend::CommitId, std::vec::Vec<commit_templater::RefName>>` and `std::collections::HashMap<jj_lib::backend::CommitId, std::vec::Vec<commit_templater::RefName>>: std::default::Default` trivially holds
     |
733  -         self.index.get(id).unwrap_or_default()
733  +         self.index.unwrap_or_default()
     |

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
Original diagnostics will follow.

warning: `jj-cli` (lib test) generated 1 warning (1 duplicate)
warning: `jj-lib` (lib test) generated 1 warning (1 duplicate)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 21.53s

Cc: #12553, which is a similar bug (but in my case, there is no mutation).

Version

rustc 1.79.0-nightly (5f2c7d2bf 2024-03-25)
binary: rustc
commit-hash: 5f2c7d2bfd46cad00352ab7cd66242077e2e518c
commit-date: 2024-03-25
host: aarch64-apple-darwin
release: 1.79.0-nightly
LLVM version: 18.1.2

Additional Labels

No response

Metadata

Metadata

Assignees

Labels

C-bugCategory: Clippy is not doing the correct thingI-false-positiveIssue: The lint was triggered on code it shouldn't have

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions