Suggest using a temporary variable to fix borrowck errors#83174
Suggest using a temporary variable to fix borrowck errors#83174bors merged 1 commit intorust-lang:masterfrom
Conversation
|
r? @oli-obk (rust-highfive has picked a reviewer for you, use r? to override) |
compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
Outdated
Show resolved
Hide resolved
This comment has been minimized.
This comment has been minimized.
|
☔ The latest upstream changes (presumably #84822) made this pull request unmergeable. Please resolve the merge conflicts. |
|
Starting with a rebase so this doesn't get too stale. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Status update: I've figured out, and implemented, a way to find the locations of |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
FYI, I just noticed this (pre-existing) test has a typo in it, but it probably shouldn't matter now that MIR borrowck is the default, right? |
camelid
left a comment
There was a problem hiding this comment.
@oli-obk I've made some progress on this. When you get a chance, could you look at the code and the errors? There are a few issues where the wrong span is used, but the false positive rate is much lower 🎉
I left comments on all the test outputs that have issues. I would appreciate suggestions on how to improve the accuracy :)
There was a problem hiding this comment.
This span's not great, but not terrible either.
There was a problem hiding this comment.
I like it more than the one that goes to the end of the call as spans won't overlap this way
There was a problem hiding this comment.
This regressed with #83174 (comment); the suggestion is no longer reported. I think let's just leave it for now.
|
📌 Commit 381b275 has been approved by |
|
🌲 The tree is currently closed for pull requests below priority 100. This pull request will be tested once the tree is reopened. |
|
@oli-obk thank you so much for helping me with this PR over the past 9 months! ❤️ |
Suggest using a temporary variable to fix borrowck errors Fixes rust-lang#77834. In Rust, nesting method calls with both require `&mut` access to `self` produces a borrow-check error: error[E0499]: cannot borrow `*self` as mutable more than once at a time --> src/lib.rs:7:14 | 7 | self.foo(self.bar()); | ---------^^^^^^^^^^- | | | | | | | second mutable borrow occurs here | | first borrow later used by call | first mutable borrow occurs here That's because Rust has a left-to-right evaluation order, and the method receiver is passed first. Thus, the argument to the method cannot then mutate `self`. There's an easy solution to this error: just extract a local variable for the inner argument: let tmp = self.bar(); self.foo(tmp); However, the error doesn't give any suggestion of how to solve the problem. As a result, new users may assume that it's impossible to express their code correctly and get stuck. This commit adds a (non-structured) suggestion to extract a local variable for the inner argument to solve the error. The suggestion uses heuristics that eliminate most false positives, though there are a few false negatives (cases where the suggestion should be emitted but is not). Those other cases can be implemented in a future change.
|
@bors r- rollup- |
In Rust, nesting method calls with both require `&mut` access to `self`
produces a borrow-check error:
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src/lib.rs:7:14
|
7 | self.foo(self.bar());
| ---------^^^^^^^^^^-
| | | |
| | | second mutable borrow occurs here
| | first borrow later used by call
| first mutable borrow occurs here
That's because Rust has a left-to-right evaluation order, and the method
receiver is passed first. Thus, the argument to the method cannot then
mutate `self`.
There's an easy solution to this error: just extract a local variable
for the inner argument:
let tmp = self.bar();
self.foo(tmp);
However, the error doesn't give any suggestion of how to solve the
problem. As a result, new users may assume that it's impossible to
express their code correctly and get stuck.
This commit adds a (non-structured) suggestion to extract a local
variable for the inner argument to solve the error. The suggestion uses
heuristics that eliminate most false positives, though there are a few
false negatives (cases where the suggestion should be emitted but is
not). Those other cases can be implemented in a future change.
| help: try adding a local storing this argument... | ||
| --> $DIR/suggest-local-var-imm-and-mut.rs:12:22 | ||
| | | ||
| LL | self.foo(self.bar()); | ||
| | ^^^^^^^^^^ | ||
| help: ...and then using that local as the argument to this call | ||
| --> $DIR/suggest-local-var-imm-and-mut.rs:12:13 | ||
| | | ||
| LL | self.foo(self.bar()); | ||
| | ^^^^^^^^^^^^^^^^^^^^ |
There was a problem hiding this comment.
It's intriguing that the suggestion doesn't show up in normal mode but does (correctly) show up in nll mode.
|
@bors r=oli-obk |
|
📌 Commit e273152 has been approved by |
Suggest using a temporary variable to fix borrowck errors Fixes rust-lang#77834. In Rust, nesting method calls with both require `&mut` access to `self` produces a borrow-check error: error[E0499]: cannot borrow `*self` as mutable more than once at a time --> src/lib.rs:7:14 | 7 | self.foo(self.bar()); | ---------^^^^^^^^^^- | | | | | | | second mutable borrow occurs here | | first borrow later used by call | first mutable borrow occurs here That's because Rust has a left-to-right evaluation order, and the method receiver is passed first. Thus, the argument to the method cannot then mutate `self`. There's an easy solution to this error: just extract a local variable for the inner argument: let tmp = self.bar(); self.foo(tmp); However, the error doesn't give any suggestion of how to solve the problem. As a result, new users may assume that it's impossible to express their code correctly and get stuck. This commit adds a (non-structured) suggestion to extract a local variable for the inner argument to solve the error. The suggestion uses heuristics that eliminate most false positives, though there are a few false negatives (cases where the suggestion should be emitted but is not). Those other cases can be implemented in a future change.
Suggest using a temporary variable to fix borrowck errors Fixes rust-lang#77834. In Rust, nesting method calls with both require `&mut` access to `self` produces a borrow-check error: error[E0499]: cannot borrow `*self` as mutable more than once at a time --> src/lib.rs:7:14 | 7 | self.foo(self.bar()); | ---------^^^^^^^^^^- | | | | | | | second mutable borrow occurs here | | first borrow later used by call | first mutable borrow occurs here That's because Rust has a left-to-right evaluation order, and the method receiver is passed first. Thus, the argument to the method cannot then mutate `self`. There's an easy solution to this error: just extract a local variable for the inner argument: let tmp = self.bar(); self.foo(tmp); However, the error doesn't give any suggestion of how to solve the problem. As a result, new users may assume that it's impossible to express their code correctly and get stuck. This commit adds a (non-structured) suggestion to extract a local variable for the inner argument to solve the error. The suggestion uses heuristics that eliminate most false positives, though there are a few false negatives (cases where the suggestion should be emitted but is not). Those other cases can be implemented in a future change.
…askrgr Rollup of 6 pull requests Successful merges: - rust-lang#83174 (Suggest using a temporary variable to fix borrowck errors) - rust-lang#89734 (Point at capture points for non-`'static` reference crossing a `yield` point) - rust-lang#90270 (Make `Borrow` and `BorrowMut` impls `const`) - rust-lang#90741 (Const `Option::cloned`) - rust-lang#91548 (Add spin_loop hint for RISC-V architecture) - rust-lang#91721 (Minor improvements to `future::join!`'s implementation) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Fixes #77834.
In Rust, nesting method calls with both require
&mutaccess toselfproduces a borrow-check error:
That's because Rust has a left-to-right evaluation order, and the method
receiver is passed first. Thus, the argument to the method cannot then
mutate
self.There's an easy solution to this error: just extract a local variable
for the inner argument:
However, the error doesn't give any suggestion of how to solve the
problem. As a result, new users may assume that it's impossible to
express their code correctly and get stuck.
This commit adds a (non-structured) suggestion to extract a local
variable for the inner argument to solve the error. The suggestion uses
heuristics that eliminate most false positives, though there are a few
false negatives (cases where the suggestion should be emitted but is
not). Those other cases can be implemented in a future change.