Skip to content

Commit e5c3dfd

Browse files
borrowck: clarify E0502 old-borrow label for field borrow vs mutable self conflicts
1 parent 8317fef commit e5c3dfd

5 files changed

Lines changed: 51 additions & 2 deletions

File tree

compiler/rustc_borrowck/src/borrowck_errors.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> {
195195
old_span: Span,
196196
noun_old: &str,
197197
kind_old: &str,
198+
old_place_desc_for_label: Option<&str>,
198199
msg_old: &str,
199200
old_load_end_span: Option<Span>,
200201
) -> Diag<'infcx> {
@@ -215,7 +216,14 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> {
215216
if msg_new.is_empty() {
216217
// If `msg_new` is empty, then this isn't a borrow of a union field.
217218
err.span_label(span, format!("{kind_new} borrow occurs here"));
218-
err.span_label(old_span, format!("{kind_old} borrow occurs here"));
219+
if let Some(old_place_desc_for_label) = old_place_desc_for_label {
220+
err.span_label(
221+
old_span,
222+
format!("{kind_old} borrow of {old_place_desc_for_label} occurs here"),
223+
);
224+
} else {
225+
err.span_label(old_span, format!("{kind_old} borrow occurs here"));
226+
}
219227
} else {
220228
// If `msg_new` isn't empty, then this a borrow of a union field.
221229
err.span_label(

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,6 +1766,16 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
17661766

17671767
let explanation = self.explain_why_borrow_contains_point(location, issued_borrow, None);
17681768
let second_borrow_desc = if explanation.is_explained() { "second " } else { "" };
1769+
let old_place_desc_for_label = if msg_place.is_empty()
1770+
&& place != issued_borrow.borrowed_place
1771+
&& place.local == issued_borrow.borrowed_place.local
1772+
&& self.local_name(place.local) == Some(kw::SelfLower)
1773+
&& place.as_ref().is_prefix_of(issued_borrow.borrowed_place.as_ref())
1774+
{
1775+
Some(self.describe_any_place(issued_borrow.borrowed_place.as_ref()))
1776+
} else {
1777+
None
1778+
};
17691779

17701780
// FIXME: supply non-"" `opt_via` when appropriate
17711781
let first_borrow_desc;
@@ -1783,6 +1793,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
17831793
issued_span,
17841794
"it",
17851795
"mutable",
1796+
old_place_desc_for_label.as_deref(),
17861797
&msg_borrow,
17871798
None,
17881799
);
@@ -1808,6 +1819,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
18081819
issued_span,
18091820
"it",
18101821
"immutable",
1822+
old_place_desc_for_label.as_deref(),
18111823
&msg_borrow,
18121824
None,
18131825
);
@@ -1910,6 +1922,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
19101922
issued_span,
19111923
"it",
19121924
"immutable",
1925+
old_place_desc_for_label.as_deref(),
19131926
&msg_borrow,
19141927
None,
19151928
)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
struct S {
2+
a: i32,
3+
}
4+
5+
impl S {
6+
fn helper(&mut self) {}
7+
8+
fn f(&mut self) {
9+
let a = &self.a;
10+
self.helper(); //~ ERROR cannot borrow `*self` as mutable because it is also borrowed as immutable
11+
a;
12+
}
13+
}
14+
15+
fn main() {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable
2+
--> $DIR/field-borrow-mut-self-issue-154275.rs:10:9
3+
|
4+
LL | let a = &self.a;
5+
| ------- immutable borrow of `self.a` occurs here
6+
LL | self.helper();
7+
| ^^^^^^^^^^^^^ mutable borrow occurs here
8+
LL | a;
9+
| - immutable borrow later used here
10+
11+
error: aborting due to 1 previous error
12+
13+
For more information about this error, try `rustc --explain E0502`.

tests/ui/borrowck/two-phase-surprise-no-conflict.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as im
1515
LL | self.hash_expr(&self.cx_mut.body(eid).value);
1616
| ^^^^^---------^^-----------^^^^^^^^^^^^^^^^^
1717
| | | |
18-
| | | immutable borrow occurs here
18+
| | | immutable borrow of `*self.cx_mut` occurs here
1919
| | immutable borrow later used by call
2020
| mutable borrow occurs here
2121

0 commit comments

Comments
 (0)