needless_borrowed_reference makes invalid suggestions
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 45/100
Research direction
Locate the implementation of the clippy::needless_borrowed_reference lint and compare its suggestion logic with the reproducer and the more complex match cases in this issue. Done means suggestions preserve required ref bindings, dereference the matched value as needed, and no longer produce code that fails to compile.
Written by the indexing model from the issue text.
Description
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
- Dominant language
- Rust
- Stars
- 13.5k
- Forks
- 2.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 32
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from rust-lang/rust-clippy
-
C-bug L-suggestion
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
rust-lang/rust-clippy#17674 · 5 comments ·
-
C-bug L-suggestion
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
rust-lang/rust-clippy#17673 · 3 comments ·
-
C-bug I-false-positive
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
rust-lang/rust-clippy#17566 ·
-
A-documentation
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
rust-lang/rust-clippy#17259 · 3 comments ·
-
A-documentation A-website C-bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
rust-lang/rust-clippy#16981 · 1 reaction ·
All issues in rust-lang/rust-clippy
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
bevyengine/bevy#25861 ·
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100