Skip to content

Commit afe70ee

Browse files
authored
Rollup merge of #86343 - JohnTitor:issue-85581, r=estebank
Do not emit invalid suggestions on multiple mutable borrow errors Fixes #85581
2 parents c062f3d + c8a8a23 commit afe70ee

File tree

4 files changed

+58
-8
lines changed

4 files changed

+58
-8
lines changed

compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs

+8
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
453453
&mut err,
454454
"",
455455
Some(borrow_span),
456+
None,
456457
);
457458
err.buffer(&mut self.errors_buffer);
458459
}
@@ -498,6 +499,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
498499
&mut err,
499500
"",
500501
None,
502+
None,
501503
);
502504
err
503505
}
@@ -718,6 +720,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
718720
&mut err,
719721
first_borrow_desc,
720722
None,
723+
Some((issued_span, span)),
721724
);
722725

723726
err
@@ -1076,6 +1079,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10761079
&mut err,
10771080
"",
10781081
None,
1082+
None,
10791083
);
10801084
}
10811085
} else {
@@ -1093,6 +1097,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10931097
&mut err,
10941098
"",
10951099
None,
1100+
None,
10961101
);
10971102
}
10981103

@@ -1158,6 +1163,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
11581163
&mut err,
11591164
"",
11601165
None,
1166+
None,
11611167
);
11621168

11631169
err.buffer(&mut self.errors_buffer);
@@ -1236,6 +1242,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
12361242
&mut err,
12371243
"",
12381244
None,
1245+
None,
12391246
);
12401247

12411248
let within = if borrow_spans.for_generator() { " by generator" } else { "" };
@@ -1614,6 +1621,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
16141621
&mut err,
16151622
"",
16161623
None,
1624+
None,
16171625
);
16181626

16191627
self.explain_deref_coercion(loan, &mut err);

compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ impl BorrowExplanation {
6666
err: &mut DiagnosticBuilder<'_>,
6767
borrow_desc: &str,
6868
borrow_span: Option<Span>,
69+
multiple_borrow_span: Option<(Span, Span)>,
6970
) {
7071
match *self {
7172
BorrowExplanation::UsedLater(later_use_kind, var_or_use_span, path_span) => {
@@ -192,14 +193,23 @@ impl BorrowExplanation {
192193

193194
if let Some(info) = &local_decl.is_block_tail {
194195
if info.tail_result_is_ignored {
195-
err.span_suggestion_verbose(
196-
info.span.shrink_to_hi(),
197-
"consider adding semicolon after the expression so its \
198-
temporaries are dropped sooner, before the local variables \
199-
declared by the block are dropped",
200-
";".to_string(),
201-
Applicability::MaybeIncorrect,
202-
);
196+
// #85581: If the first mutable borrow's scope contains
197+
// the second borrow, this suggestion isn't helpful.
198+
if !multiple_borrow_span
199+
.map(|(old, new)| {
200+
old.to(info.span.shrink_to_hi()).contains(new)
201+
})
202+
.unwrap_or(false)
203+
{
204+
err.span_suggestion_verbose(
205+
info.span.shrink_to_hi(),
206+
"consider adding semicolon after the expression so its \
207+
temporaries are dropped sooner, before the local variables \
208+
declared by the block are dropped",
209+
";".to_string(),
210+
Applicability::MaybeIncorrect,
211+
);
212+
}
203213
} else {
204214
err.note(
205215
"the temporary is part of an expression at the end of a \

src/test/ui/borrowck/issue-85581.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Regression test of #85581.
2+
// Checks not to suggest to add `;` when the second mutable borrow
3+
// is in the first's scope.
4+
5+
use std::collections::BinaryHeap;
6+
7+
fn foo(heap: &mut BinaryHeap<i32>) {
8+
match heap.peek_mut() {
9+
Some(_) => { heap.pop(); },
10+
//~^ ERROR: cannot borrow `*heap` as mutable more than once at a time
11+
None => (),
12+
}
13+
}
14+
15+
fn main() {}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0499]: cannot borrow `*heap` as mutable more than once at a time
2+
--> $DIR/issue-85581.rs:9:22
3+
|
4+
LL | match heap.peek_mut() {
5+
| ---------------
6+
| |
7+
| first mutable borrow occurs here
8+
| a temporary with access to the first borrow is created here ...
9+
LL | Some(_) => { heap.pop(); },
10+
| ^^^^ second mutable borrow occurs here
11+
...
12+
LL | }
13+
| - ... and the first borrow might be used here, when that temporary is dropped and runs the destructor for type `Option<PeekMut<'_, i32>>`
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0499`.

0 commit comments

Comments
 (0)