Skip to content

needless_borrowed_reference makes invalid suggestions #13035

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wr7 opened this issue Jul 3, 2024 · 1 comment
Open

needless_borrowed_reference makes invalid suggestions #13035

wr7 opened this issue Jul 3, 2024 · 1 comment
Labels
C-bug Category: Clippy is not doing the correct thing I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied

Comments

@wr7
Copy link

wr7 commented Jul 3, 2024

Summary

&ref in a match arm can perform dereferencing, and clippy::needless_borrowed_reference does not seem to take this into consideration.

Lint Name

clippy::needless_borrowed_reference

Reproducer

I tried this code:

pub enum HasData<'a> {
    V(&'a [u8]),
}

fn expects_box(_: Box<[u8]>) {}

pub fn foo(val: &HasData) {
    match val {
        HasData::V(&ref data) => expects_box(data.into()),
    }
}

cargo clippy --fix output:

The following errors were reported:
error[E0277]: the trait bound `std::boxed::Box<[u8]>: std::convert::From<&&[u8]>` is not satisfied
 --> src/lib.rs:9:46
  |
9 |         HasData::V(data) => expects_box(data.into()),
  |                                              ^^^^ the trait `std::convert::From<&&[u8]>` is not implemented for `std::boxed::Box<[u8]>`, which is required by `&&[u8]: std::convert::Into<_>`
  |
  = help: the following other types implement trait `std::convert::From<T>`:
            <std::boxed::Box<(dyn std::error::Error + 'a)> as std::convert::From<&str>>
            <std::boxed::Box<(dyn std::error::Error + 'a)> as std::convert::From<E>>
            <std::boxed::Box<(dyn std::error::Error + 'a)> as std::convert::From<std::borrow::Cow<'b, str>>>
            <std::boxed::Box<(dyn std::error::Error + 'a)> as std::convert::From<std::string::String>>
            <std::boxed::Box<(dyn std::error::Error + std::marker::Send + std::marker::Sync + 'a)> as std::convert::From<&str>>
            <std::boxed::Box<(dyn std::error::Error + std::marker::Send + std::marker::Sync + 'a)> as std::convert::From<E>>
            <std::boxed::Box<(dyn std::error::Error + std::marker::Send + std::marker::Sync + 'a)> as std::convert::From<std::borrow::Cow<'b, str>>>
            <std::boxed::Box<(dyn std::error::Error + std::marker::Send + std::marker::Sync + 'a)> as std::convert::From<std::string::String>>
          and 18 others
  = note: required for `&&[u8]` to implement `std::convert::Into<std::boxed::Box<[u8]>>`

error: aborting due to 1 previous error

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

warning: this pattern takes a reference on something that is being dereferenced
 --> src/lib.rs:9:20
  |
9 |         HasData::V(&ref data) => expects_box(data.into()),
  |                    ^^^^^^^^^
  |
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
  = note: `#[warn(clippy::needless_borrowed_reference)]` on by default
help: try removing the `&ref` part
  |
9 -         HasData::V(&ref data) => expects_box(data.into()),
9 +         HasData::V(data) => expects_box(data.into()),
  |

warning: `rust-test` (lib test) generated 1 warning (run `cargo clippy --fix --lib -p rust-test --tests` to apply 1 suggestion)
warning: failed to automatically apply fixes suggested by rustc to crate `rust_test`

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

  * src/lib.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::boxed::Box<[u8]>: std::convert::From<&&[u8]>` is not satisfied
 --> src/lib.rs:9:46
  |
9 |         HasData::V(data) => expects_box(data.into()),
  |                                              ^^^^ the trait `std::convert::From<&&[u8]>` is not implemented for `std::boxed::Box<[u8]>`, which is required by `&&[u8]: std::convert::Into<_>`
  |
  = help: the following other types implement trait `std::convert::From<T>`:
            <std::boxed::Box<(dyn std::error::Error + 'a)> as std::convert::From<&str>>
            <std::boxed::Box<(dyn std::error::Error + 'a)> as std::convert::From<E>>
            <std::boxed::Box<(dyn std::error::Error + 'a)> as std::convert::From<std::borrow::Cow<'b, str>>>
            <std::boxed::Box<(dyn std::error::Error + 'a)> as std::convert::From<std::string::String>>
            <std::boxed::Box<(dyn std::error::Error + std::marker::Send + std::marker::Sync + 'a)> as std::convert::From<&str>>
            <std::boxed::Box<(dyn std::error::Error + std::marker::Send + std::marker::Sync + 'a)> as std::convert::From<E>>
            <std::boxed::Box<(dyn std::error::Error + std::marker::Send + std::marker::Sync + 'a)> as std::convert::From<std::borrow::Cow<'b, str>>>
            <std::boxed::Box<(dyn std::error::Error + std::marker::Send + std::marker::Sync + 'a)> as std::convert::From<std::string::String>>
          and 18 others
  = note: required for `&&[u8]` to implement `std::convert::Into<std::boxed::Box<[u8]>>`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.

Expected behavior

Add a deref to val and then remove the &ref

pub enum HasData<'a> {
    V(&'a [u8]),
}

fn expects_box(_: Box<[u8]>) {}

pub fn foo(val: &HasData) {
    match *val {
        HasData::V(data) => expects_box(data.into()),
    }
}

More complex cases

More complex cases should not be corrected or the following corrections should be applied.

Other match variables

ref should be added to other matched variables.

The following example

pub enum HasData<'a> {
    U(String),
    V(&'a [u8]),
}

fn expects_box(_: Box<[u8]>) {}
fn expects_str(_: &str) {}

pub fn foo(val: &HasData) {
    match val {
        HasData::U(string) => expects_str(string),
        HasData::V(&ref data) => expects_box(data.into()),
    }
}

should be corrected to:

pub enum HasData<'a> {
    U(String),
    V(&'a [u8]),
}

fn expects_box(_: Box<[u8]>) {}
fn expects_str(_: &str) {}

pub fn foo(val: &HasData) {
    match *val {
        HasData::U(ref string) => expects_str(string),
        HasData::V(data) => expects_box(data.into()),
    }
}

Multiple references

The matched value should be dereferenced until it is bare.

The following example

pub enum HasData<'a> {
    U(String),
    V(&'a [u8]),
}

fn expects_box(_: Box<[u8]>) {}
fn expects_str(_: &str) {}

pub fn foo(val: &&HasData) {
    match val {
        HasData::U(string) => expects_str(string),
        HasData::V(&ref data) => expects_box(data.into()),
    }
}

should be corrected to:

pub enum HasData<'a> {
    U(String),
    V(&'a [u8]),
}

fn expects_box(_: Box<[u8]>) {}
fn expects_str(_: &str) {}

pub fn foo(val: &&HasData) {
    match **val {
        HasData::U(ref string) => expects_str(string),
        HasData::V(data) => expects_box(data.into()),
    }
}

Version

rustc 1.79.0 (129f3b996 2024-06-10)
binary: rustc
commit-hash: 129f3b9964af4d4a709d1383930ade12dfe7c081
commit-date: 2024-06-10
host: x86_64-unknown-linux-gnu
release: 1.79.0
LLVM version: 18.1.7

Additional Labels

@rustbot label +I-suggestion-causes-error
@rustbot label -I-false-positive

@wr7 wr7 added C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have labels Jul 3, 2024
@rustbot rustbot added the I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied label Jul 3, 2024
@wr7 wr7 changed the title needless_borrowed_reference makes broken suggestion needless_borrowed_reference makes invalid suggestions Jul 3, 2024
@rustbot rustbot removed the I-false-positive Issue: The lint was triggered on code it shouldn't have label Jul 3, 2024
@tyilo
Copy link

tyilo commented Jan 29, 2025

Another instance of this:

#[derive(Debug)]
struct NonCopy;

fn main() {
    let v = vec![NonCopy];
    let &[ref x] = v.as_slice().try_into().unwrap();
    println!("{x:?}");
}

clippy gives the following suggestion:

warning: dereferencing a slice pattern where every element takes a reference
 --> src/main.rs:6:9
  |
6 |     let &[ref x] = v.as_slice().try_into().unwrap();
  |         ^^^^^^^^
  |
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
  = note: `#[warn(clippy::needless_borrowed_reference)]` on by default
help: try removing the `&` and `ref` parts
  |
6 -     let &[ref x] = v.as_slice().try_into().unwrap();
6 +     let [x] = v.as_slice().try_into().unwrap();
  |

applying it results in:

error[E0277]: the trait bound `[_; 1]: std::convert::TryFrom<&[NonCopy]>` is not satisfied
 --> src/main.rs:6:28
  |
6 |     let [x] = v.as_slice().try_into().unwrap();
  |                            ^^^^^^^^ the trait `std::convert::TryFrom<&[NonCopy]>` is not implemented for `[_; 1]`
  |
  = help: the following other types implement trait `std::convert::TryFrom<T>`:
            `&[T; N]` implements `std::convert::TryFrom<&[T]>`
            `&mut [T; N]` implements `std::convert::TryFrom<&mut [T]>`
            `[T; N]` implements `std::convert::TryFrom<&[T]>`
            `[T; N]` implements `std::convert::TryFrom<&mut [T]>`
            `[T; N]` implements `std::convert::TryFrom<std::vec::Vec<T, A>>`
  = note: required for `&[NonCopy]` to implement `std::convert::TryInto<[_; 1]>`

For more information about this error, try `rustc --explain E0277`.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied
Projects
None yet
Development

No branches or pull requests

3 participants