Skip to content

needless_borrow false positive in case when compiler does not automatically borrow #9111

@leighmcculloch

Description

@leighmcculloch

Summary

The needless_borrow lint has a false positive where the suggested fix results in code that won't compile, because the compiler doesn't automatically borrow, even though the lint says it does.

Lint Name

needless_borrow

Reproducer

I tried this code:

#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct VecM<T, const MAX: u32 = { u32::MAX }>(Vec<T>);

impl<T: Clone, const N: usize, const MAX: u32> TryFrom<&[T; N]> for VecM<T, MAX> {
    type Error = ();

    fn try_from(v: &[T; N]) -> Result<Self, ()> {
        todo!()
    }
}

#[cfg(test)]
mod test {
    use crate::VecM;

    #[test]
    fn test_try_from() {
        let _vm: VecM<u8, 32> = (&[]).try_into().unwrap();
        //let _vm: VecM<u8, 32> = [].try_into().unwrap();
    }
}
❯ cargo clippy --all-targets
    Checking clippy-needless-borrow v0.1.0 (/Users/leighmcculloch/Code/clippy-needless-borrow)
warning: this expression borrows a value the compiler would automatically borrow
  --> src/lib.rs:23:33
   |
18 |         let _vm: VecM<u8, 32> = (&[]).try_into().unwrap();
   |                                 ^^^^^ help: change this to: `[]`
   |
   = note: `#[warn(clippy::needless_borrow)]` on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

warning: `clippy-needless-borrow` (lib test) generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 0.12s

Making the change that clippy suggests, results in the following and the following compiler error:

#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct VecM<T, const MAX: u32 = { u32::MAX }>(Vec<T>);

impl<T: Clone, const N: usize, const MAX: u32> TryFrom<&[T; N]> for VecM<T, MAX> {
    type Error = ();

    fn try_from(v: &[T; N]) -> Result<Self, ()> {
        todo!()
    }
}

#[cfg(test)]
mod test {
    use crate::VecM;

    #[test]
    fn test_try_from() {
        //let _vm: VecM<u8, 32> = (&[]).try_into().unwrap();
        let _vm: VecM<u8, 32> = [].try_into().unwrap();
    }
}
❯ cargo clippy --all-targets
    Checking clippy-needless-borrow v0.1.0 (/Users/leighmcculloch/Code/clippy-needless-borrow)
error[E0277]: the trait bound `VecM<u8, 32_u32>: std::convert::From<[_; 0]>` is not satisfied
  --> src/lib.rs:24:36
   |
19 |         let _vm: VecM<u8, 32> = [].try_into().unwrap();
   |                                    ^^^^^^^^ the trait `std::convert::From<[_; 0]>` is not implemented for `VecM<u8, 32_u32>`
   |
   = note: required because of the requirements on the impl of `std::convert::Into<VecM<u8, 32_u32>>` for `[_; 0]`
   = note: required because of the requirements on the impl of `std::convert::TryFrom<[_; 0]>` for `VecM<u8, 32_u32>`
   = note: required because of the requirements on the impl of `std::convert::TryInto<VecM<u8, 32_u32>>` for `[_; 0]`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `clippy-needless-borrow` due to previous error

Version

❯ rustc -Vv
rustc 1.64.0-nightly (f2d93935f 2022-07-02)
binary: rustc
commit-hash: f2d93935ffba3ab9d7ccb5300771a2d29b4c8bf3
commit-date: 2022-07-02
host: x86_64-apple-darwin
release: 1.64.0-nightly
LLVM version: 14.0.6

Additional Labels

@rustbot label +I-suggestion-causes-error

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thingI-false-positiveIssue: The lint was triggered on code it shouldn't haveI-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