Closed
Description
openedon Jan 25, 2021
The following code:
use std::ops::Deref;
struct DerefTarget {
target_field: bool
}
struct Container {
target: DerefTarget,
container_field: bool,
}
impl Deref for Container {
type Target = DerefTarget;
fn deref(&self) -> &Self::Target {
&self.target
}
}
impl Container {
fn bad_borrow(&mut self) {
let first = &self.target_field;
self.container_field = true;
first;
}
}
causes the following error message:
error[E0506]: cannot assign to `self.container_field` because it is borrowed
--> src/lib.rs:21:9
|
20 | let first = &self.target_field;
| ---- borrow of `self.container_field` occurs here
21 | self.container_field = true;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `self.container_field` occurs here
22 | first;
| ----- borrow later used here
This error is caused by the fact that &self.target_field
does through the Deref
impl on Container
. As a result, &self
is borrowed, not just the desired field. Changing this line to let first = &self.target.target_field
makes the code compile.
However, the error message doesn't explain any of this. It claims that the usage of self
is a borrow of self.container_field
, without noting that this is due to the Deref
impl.
We should do something similar to #75304 for borrows, and make it clear when lifetimes are being affected by implicit Deref
calls.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Metadata
Assignees
Labels
Area: The borrow checkerArea: Messages for errors, warnings, and lintsCategory: This is a bug.Diagnostics: Confusing error or lint that should be reworked.Diagnostics: Confusing error or lint; hard to understand for new users.Relevant to the compiler team, which will review and decide on the PR/issue.