Detect mut arg: &Ty meant to be arg: &mut Ty and provide structured suggestion#134977
Detect mut arg: &Ty meant to be arg: &mut Ty and provide structured suggestion#134977bors merged 4 commits intorust-lang:masterfrom
mut arg: &Ty meant to be arg: &mut Ty and provide structured suggestion#134977Conversation
This comment has been minimized.
This comment has been minimized.
|
If this is considered too esoteric, I'm ok with closing the PR and ticket, but it feels directionally correct to me. |
be0cfb3 to
f4df967
Compare
This comment has been minimized.
This comment has been minimized.
f4df967 to
b5ecbe0
Compare
| 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; | ||
| | |
There was a problem hiding this comment.
I think this help: only being on the warning instead of the actual error makes it far less useful 🤔 Personally I just skip over all the warnings when i have a compiler error so would likely not even see this in my own workflow.
Is it particularly difficult to give the help on the borrowck error, I could definitely understand if it seems like a lot more work and you just don't want to deal with that.
There was a problem hiding this comment.
Agreed on all accounts. You got it right. I'd want us to come back to this and handle it in borrock, but landing a partial solution earlier feels better than waiting until I come up with a full solution.
| LL ~ fn change_object(object: &mut Object) { | ||
| LL | let object2 = Object; | ||
| LL ~ *object = object2; |
There was a problem hiding this comment.
The simple case works though so 🤷♀️ still valuable
|
|
||
| fn change_object(mut object: &Object) { | ||
| let object2 = Object; | ||
| object = object2; //~ ERROR mismatched types |
There was a problem hiding this comment.
Would you want to add a //~| HELP: annotation so that we continue testing that the help note you added, stays
| .iter() | ||
| .filter_map(|ty| { | ||
| if ty.span == *ty_span | ||
| && let hir::TyKind::Ref(lt, mut_ty) = ty.kind |
There was a problem hiding this comment.
why mut_ty? this isnt a &mut ref its some &ty
There was a problem hiding this comment.
mut_ty because the second positional field of Ref is MutTy, as in "mutability and type". Granted, the name is barely a step above x, and arguably would be better if it was x.
| }) | ||
| .next() | ||
| else { | ||
| return false; |
There was a problem hiding this comment.
can you not use like 10 different let ... else ... in this function and use a series of let chains instead like we do in annotate_mut_binding_to_immutable_binding. There's so much noise reading this with all the else { return false; } taking up multiple lines after practically every check in this function
There was a problem hiding this comment.
Not convinced that these long chains of conditions look better as let chains or let elses. I flip flop on my opinion by the hour 😅
There was a problem hiding this comment.
Yeah both always feel kind of gruelling to read lol...
This is a mistake I've seen newcomers make where they want to express an "out" argument.
```
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;
|
```
This might be the first thing someone tries to write to mutate the value *behind* an argument. We avoid suggesting `object = &object2;`, as that is less likely to be what was intended.
```
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;
|
```
This might be the first thing someone tries to write to mutate the value *behind* an argument, trying to avoid an E0308.
b5ecbe0 to
4438b32
Compare
|
@bors r+ rollup |
Rollup of 10 pull requests Successful merges: - rust-lang#134498 (Fix cycle error only occurring with -Zdump-mir) - rust-lang#134977 (Detect `mut arg: &Ty` meant to be `arg: &mut Ty` and provide structured suggestion) - rust-lang#135390 (Re-added regression test for rust-lang#122638) - rust-lang#135393 (uefi: helpers: Introduce OwnedDevicePath) - rust-lang#135440 (rm unnecessary `OpaqueTypeDecl` wrapper) - rust-lang#135441 (Make sure to mark `IMPL_TRAIT_REDUNDANT_CAPTURES` as `Allow` in edition 2024) - rust-lang#135444 (Update books) - rust-lang#135450 (Fix emscripten-wasm-eh with unwind=abort) - rust-lang#135452 (bootstrap: fix outdated feature name in comment) - rust-lang#135454 (llvm: Allow sized-word rather than ymmword in tests) r? `@ghost` `@rustbot` modify labels: rollup
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.
Rollup of 10 pull requests Successful merges: - rust-lang#134498 (Fix cycle error only occurring with -Zdump-mir) - rust-lang#134977 (Detect `mut arg: &Ty` meant to be `arg: &mut Ty` and provide structured suggestion) - rust-lang#135390 (Re-added regression test for rust-lang#122638) - rust-lang#135393 (uefi: helpers: Introduce OwnedDevicePath) - rust-lang#135440 (rm unnecessary `OpaqueTypeDecl` wrapper) - rust-lang#135441 (Make sure to mark `IMPL_TRAIT_REDUNDANT_CAPTURES` as `Allow` in edition 2024) - rust-lang#135444 (Update books) - rust-lang#135450 (Fix emscripten-wasm-eh with unwind=abort) - rust-lang#135452 (bootstrap: fix outdated feature name in comment) - rust-lang#135454 (llvm: Allow sized-word rather than ymmword in tests) r? `@ghost` `@rustbot` modify labels: rollup
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
and to the unused assignment lint
Fix #112357.