Auto merge of #12843 - mdm:fix-unnecessary-to-owned-println-interaction, r=y21
Fix `unnecessary_to_owned` interaction with macro expansion fixes #12821 In the case of an unnecessary `.iter().cloned()`, the lint `unnecessary_to_owned` might suggest to remove the `&` from references without checking if such references are inside a macro expansion. This can lead to unexpected behavior or even broken code if the lint suggestion is applied blindly. See issue #12821 for an example. This PR checks if such references are inside macro expansions and skips this part of the lint suggestion in these cases. changelog: [`unnecessary_to_owned`]: Don't suggest to remove `&` inside macro expansion
This commit is contained in:
commit
7e4c1ae0b6
6 changed files with 117 additions and 19 deletions
|
|
@ -170,3 +170,32 @@ fn check_mut_iteratee_and_modify_inner_variable() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod issue_12821 {
|
||||
fn foo() {
|
||||
let v: Vec<_> = "hello".chars().collect();
|
||||
for c in v.iter() {
|
||||
//~^ ERROR: unnecessary use of `cloned`
|
||||
println!("{c}"); // should not suggest to remove `&`
|
||||
}
|
||||
}
|
||||
|
||||
fn bar() {
|
||||
let v: Vec<_> = "hello".chars().collect();
|
||||
for c in v.iter() {
|
||||
//~^ ERROR: unnecessary use of `cloned`
|
||||
let ref_c = c; //~ HELP: remove any references to the binding
|
||||
println!("{ref_c}");
|
||||
}
|
||||
}
|
||||
|
||||
fn baz() {
|
||||
let v: Vec<_> = "hello".chars().enumerate().collect();
|
||||
for (i, c) in v.iter() {
|
||||
//~^ ERROR: unnecessary use of `cloned`
|
||||
let ref_c = c; //~ HELP: remove any references to the binding
|
||||
let ref_i = i;
|
||||
println!("{i} {ref_c}"); // should not suggest to remove `&` from `i`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,3 +170,32 @@ fn check_mut_iteratee_and_modify_inner_variable() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod issue_12821 {
|
||||
fn foo() {
|
||||
let v: Vec<_> = "hello".chars().collect();
|
||||
for c in v.iter().cloned() {
|
||||
//~^ ERROR: unnecessary use of `cloned`
|
||||
println!("{c}"); // should not suggest to remove `&`
|
||||
}
|
||||
}
|
||||
|
||||
fn bar() {
|
||||
let v: Vec<_> = "hello".chars().collect();
|
||||
for c in v.iter().cloned() {
|
||||
//~^ ERROR: unnecessary use of `cloned`
|
||||
let ref_c = &c; //~ HELP: remove any references to the binding
|
||||
println!("{ref_c}");
|
||||
}
|
||||
}
|
||||
|
||||
fn baz() {
|
||||
let v: Vec<_> = "hello".chars().enumerate().collect();
|
||||
for (i, c) in v.iter().cloned() {
|
||||
//~^ ERROR: unnecessary use of `cloned`
|
||||
let ref_c = &c; //~ HELP: remove any references to the binding
|
||||
let ref_i = &i;
|
||||
println!("{i} {ref_c}"); // should not suggest to remove `&` from `i`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ help: use
|
|||
|
|
||||
LL | for (t, path) in files {
|
||||
| ~~~~~
|
||||
help: remove this `&`
|
||||
help: remove any references to the binding
|
||||
|
|
||||
LL - let other = match get_file_path(&t) {
|
||||
LL + let other = match get_file_path(t) {
|
||||
|
|
@ -26,11 +26,49 @@ help: use
|
|||
|
|
||||
LL | for (t, path) in files.iter() {
|
||||
| ~~~~~~~~~~~~
|
||||
help: remove this `&`
|
||||
help: remove any references to the binding
|
||||
|
|
||||
LL - let other = match get_file_path(&t) {
|
||||
LL + let other = match get_file_path(t) {
|
||||
|
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: unnecessary use of `cloned`
|
||||
--> tests/ui/unnecessary_iter_cloned.rs:177:18
|
||||
|
|
||||
LL | for c in v.iter().cloned() {
|
||||
| ^^^^^^^^^^^^^^^^^ help: use: `v.iter()`
|
||||
|
||||
error: unnecessary use of `cloned`
|
||||
--> tests/ui/unnecessary_iter_cloned.rs:185:18
|
||||
|
|
||||
LL | for c in v.iter().cloned() {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use
|
||||
|
|
||||
LL | for c in v.iter() {
|
||||
| ~~~~~~~~
|
||||
help: remove any references to the binding
|
||||
|
|
||||
LL - let ref_c = &c;
|
||||
LL + let ref_c = c;
|
||||
|
|
||||
|
||||
error: unnecessary use of `cloned`
|
||||
--> tests/ui/unnecessary_iter_cloned.rs:194:23
|
||||
|
|
||||
LL | for (i, c) in v.iter().cloned() {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use
|
||||
|
|
||||
LL | for (i, c) in v.iter() {
|
||||
| ~~~~~~~~
|
||||
help: remove any references to the binding
|
||||
|
|
||||
LL ~ let ref_c = c;
|
||||
LL ~ let ref_i = i;
|
||||
|
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -487,7 +487,7 @@ help: use
|
|||
|
|
||||
LL | for t in file_types {
|
||||
| ~~~~~~~~~~
|
||||
help: remove this `&`
|
||||
help: remove any references to the binding
|
||||
|
|
||||
LL - let path = match get_file_path(&t) {
|
||||
LL + let path = match get_file_path(t) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue