Closed
Description
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.
Metadata
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.
Activity
sledgehammervampire commentedon Jan 25, 2021
@rustbot claim
sledgehammervampire commentedon Jan 31, 2021
@Aaron1011 How can I check if a
Deref
in the list of projections of a place is implicitly inserted?Aaron1011 commentedon Jan 31, 2021
@1000teslas: You should be able to adapt this code:
rust/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs
Lines 798 to 893 in 0677d97
and re-use the
FnSelfUse
code. The actual check for a non-user-suppliedDeref
call is done by:rust/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs
Line 835 in 0677d97
sledgehammervampire commentedon Feb 5, 2021
@Aaron1011 It doesn't look like
from_hir_call
distinguishes betweenissue-81365.rs
, where the deref inself.target_field
is implicit andissue-81365-8.rs
, where the deref is explicit.Rollup merge of rust-lang#81629 - 1000teslas:issue-81365-fix, r=Aaron…