forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#134977 - estebank:issue-112357, r=BoxyUwU Detect `mut arg: &Ty` meant to be `arg: &mut Ty` and provide structured suggestion When a newcomer attempts to use an "out parameter" using borrows, they sometimes get confused and instead of mutating the borrow they try to mutate the function-local binding instead. This leads to either type errors (due to assigning an owned value to a mutable binding of reference type) or a multitude of lifetime errors and unused binding warnings. This change adds a suggestion to the type error ``` error[E0308]: mismatched types --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:6:14 | LL | fn change_object(mut object: &Object) { | ------- expected due to this parameter type LL | let object2 = Object; LL | object = object2; | ^^^^^^^ expected `&Object`, found `Object` | help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding | LL ~ fn change_object(object: &mut Object) { LL | let object2 = Object; LL ~ *object = object2; | ``` and to the unused assignment lint ``` error: value assigned to `object` is never read --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:11:5 | LL | object = &object2; | ^^^^^^ | note: the lint level is defined here --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:1:9 | LL | #![deny(unused_assignments, unused_variables)] | ^^^^^^^^^^^^^^^^^^ help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding | LL ~ fn change_object2(object: &mut Object) { LL | let object2 = Object; LL ~ *object = object2; | ``` Fix rust-lang#112357.
- Loading branch information
Showing
7 changed files
with
306 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.fixed
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
//@ run-rustfix | ||
#![deny(unused_assignments, unused_variables)] | ||
struct Object; | ||
|
||
fn change_object(object: &mut Object) { //~ HELP you might have meant to mutate | ||
let object2 = Object; | ||
*object = object2; //~ ERROR mismatched types | ||
} | ||
|
||
fn change_object2(object: &mut Object) { //~ ERROR variable `object` is assigned to, but never used | ||
//~^ HELP you might have meant to mutate | ||
let object2 = Object; | ||
*object = object2; | ||
//~^ ERROR `object2` does not live long enough | ||
//~| ERROR value assigned to `object` is never read | ||
} | ||
|
||
fn main() { | ||
let mut object = Object; | ||
change_object(&mut object); | ||
change_object2(&mut object); | ||
} |
22 changes: 22 additions & 0 deletions
22
tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
//@ run-rustfix | ||
#![deny(unused_assignments, unused_variables)] | ||
struct Object; | ||
|
||
fn change_object(mut object: &Object) { //~ HELP you might have meant to mutate | ||
let object2 = Object; | ||
object = object2; //~ ERROR mismatched types | ||
} | ||
|
||
fn change_object2(mut object: &Object) { //~ ERROR variable `object` is assigned to, but never used | ||
//~^ HELP you might have meant to mutate | ||
let object2 = Object; | ||
object = &object2; | ||
//~^ ERROR `object2` does not live long enough | ||
//~| ERROR value assigned to `object` is never read | ||
} | ||
|
||
fn main() { | ||
let mut object = Object; | ||
change_object(&mut object); | ||
change_object2(&mut object); | ||
} |
69 changes: 69 additions & 0 deletions
69
tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
error[E0308]: mismatched types | ||
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:7:14 | ||
| | ||
LL | fn change_object(mut object: &Object) { | ||
| ------- expected due to this parameter type | ||
LL | let object2 = Object; | ||
LL | object = object2; | ||
| ^^^^^^^ expected `&Object`, found `Object` | ||
| | ||
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding | ||
| | ||
LL ~ fn change_object(object: &mut Object) { | ||
LL | let object2 = Object; | ||
LL ~ *object = object2; | ||
| | ||
|
||
error: value assigned to `object` is never read | ||
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:13:5 | ||
| | ||
LL | object = &object2; | ||
| ^^^^^^ | ||
| | ||
note: the lint level is defined here | ||
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:2:9 | ||
| | ||
LL | #![deny(unused_assignments, unused_variables)] | ||
| ^^^^^^^^^^^^^^^^^^ | ||
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding | ||
| | ||
LL ~ fn change_object2(object: &mut Object) { | ||
LL | | ||
LL | let object2 = Object; | ||
LL ~ *object = object2; | ||
| | ||
|
||
error: variable `object` is assigned to, but never used | ||
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:10:23 | ||
| | ||
LL | fn change_object2(mut object: &Object) { | ||
| ^^^^^^ | ||
| | ||
= note: consider using `_object` instead | ||
note: the lint level is defined here | ||
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:2:29 | ||
| | ||
LL | #![deny(unused_assignments, unused_variables)] | ||
| ^^^^^^^^^^^^^^^^ | ||
|
||
error[E0597]: `object2` does not live long enough | ||
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:13:14 | ||
| | ||
LL | fn change_object2(mut object: &Object) { | ||
| - let's call the lifetime of this reference `'1` | ||
LL | | ||
LL | let object2 = Object; | ||
| ------- binding `object2` declared here | ||
LL | object = &object2; | ||
| ---------^^^^^^^^ | ||
| | | | ||
| | borrowed value does not live long enough | ||
| assignment requires that `object2` is borrowed for `'1` | ||
... | ||
LL | } | ||
| - `object2` dropped here while still borrowed | ||
|
||
error: aborting due to 4 previous errors | ||
|
||
Some errors have detailed explanations: E0308, E0597. | ||
For more information about an error, try `rustc --explain E0308`. |