Rollup merge of #86343 - JohnTitor:issue-85581, r=estebank
Do not emit invalid suggestions on multiple mutable borrow errors Fixes #85581
This commit is contained in:
commit
afe70ee440
@ -453,6 +453,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
&mut err,
|
&mut err,
|
||||||
"",
|
"",
|
||||||
Some(borrow_span),
|
Some(borrow_span),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
err.buffer(&mut self.errors_buffer);
|
err.buffer(&mut self.errors_buffer);
|
||||||
}
|
}
|
||||||
@ -498,6 +499,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
&mut err,
|
&mut err,
|
||||||
"",
|
"",
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
@ -718,6 +720,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
&mut err,
|
&mut err,
|
||||||
first_borrow_desc,
|
first_borrow_desc,
|
||||||
None,
|
None,
|
||||||
|
Some((issued_span, span)),
|
||||||
);
|
);
|
||||||
|
|
||||||
err
|
err
|
||||||
@ -1076,6 +1079,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
&mut err,
|
&mut err,
|
||||||
"",
|
"",
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1093,6 +1097,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
&mut err,
|
&mut err,
|
||||||
"",
|
"",
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1158,6 +1163,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
&mut err,
|
&mut err,
|
||||||
"",
|
"",
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
err.buffer(&mut self.errors_buffer);
|
err.buffer(&mut self.errors_buffer);
|
||||||
@ -1236,6 +1242,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
&mut err,
|
&mut err,
|
||||||
"",
|
"",
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
let within = if borrow_spans.for_generator() { " by generator" } else { "" };
|
let within = if borrow_spans.for_generator() { " by generator" } else { "" };
|
||||||
@ -1614,6 +1621,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
&mut err,
|
&mut err,
|
||||||
"",
|
"",
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.explain_deref_coercion(loan, &mut err);
|
self.explain_deref_coercion(loan, &mut err);
|
||||||
|
@ -66,6 +66,7 @@ impl BorrowExplanation {
|
|||||||
err: &mut DiagnosticBuilder<'_>,
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
borrow_desc: &str,
|
borrow_desc: &str,
|
||||||
borrow_span: Option<Span>,
|
borrow_span: Option<Span>,
|
||||||
|
multiple_borrow_span: Option<(Span, Span)>,
|
||||||
) {
|
) {
|
||||||
match *self {
|
match *self {
|
||||||
BorrowExplanation::UsedLater(later_use_kind, var_or_use_span, path_span) => {
|
BorrowExplanation::UsedLater(later_use_kind, var_or_use_span, path_span) => {
|
||||||
@ -192,14 +193,23 @@ impl BorrowExplanation {
|
|||||||
|
|
||||||
if let Some(info) = &local_decl.is_block_tail {
|
if let Some(info) = &local_decl.is_block_tail {
|
||||||
if info.tail_result_is_ignored {
|
if info.tail_result_is_ignored {
|
||||||
err.span_suggestion_verbose(
|
// #85581: If the first mutable borrow's scope contains
|
||||||
info.span.shrink_to_hi(),
|
// the second borrow, this suggestion isn't helpful.
|
||||||
"consider adding semicolon after the expression so its \
|
if !multiple_borrow_span
|
||||||
temporaries are dropped sooner, before the local variables \
|
.map(|(old, new)| {
|
||||||
declared by the block are dropped",
|
old.to(info.span.shrink_to_hi()).contains(new)
|
||||||
";".to_string(),
|
})
|
||||||
Applicability::MaybeIncorrect,
|
.unwrap_or(false)
|
||||||
);
|
{
|
||||||
|
err.span_suggestion_verbose(
|
||||||
|
info.span.shrink_to_hi(),
|
||||||
|
"consider adding semicolon after the expression so its \
|
||||||
|
temporaries are dropped sooner, before the local variables \
|
||||||
|
declared by the block are dropped",
|
||||||
|
";".to_string(),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
err.note(
|
err.note(
|
||||||
"the temporary is part of an expression at the end of a \
|
"the temporary is part of an expression at the end of a \
|
||||||
|
15
src/test/ui/borrowck/issue-85581.rs
Normal file
15
src/test/ui/borrowck/issue-85581.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Regression test of #85581.
|
||||||
|
// Checks not to suggest to add `;` when the second mutable borrow
|
||||||
|
// is in the first's scope.
|
||||||
|
|
||||||
|
use std::collections::BinaryHeap;
|
||||||
|
|
||||||
|
fn foo(heap: &mut BinaryHeap<i32>) {
|
||||||
|
match heap.peek_mut() {
|
||||||
|
Some(_) => { heap.pop(); },
|
||||||
|
//~^ ERROR: cannot borrow `*heap` as mutable more than once at a time
|
||||||
|
None => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
17
src/test/ui/borrowck/issue-85581.stderr
Normal file
17
src/test/ui/borrowck/issue-85581.stderr
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
error[E0499]: cannot borrow `*heap` as mutable more than once at a time
|
||||||
|
--> $DIR/issue-85581.rs:9:22
|
||||||
|
|
|
||||||
|
LL | match heap.peek_mut() {
|
||||||
|
| ---------------
|
||||||
|
| |
|
||||||
|
| first mutable borrow occurs here
|
||||||
|
| a temporary with access to the first borrow is created here ...
|
||||||
|
LL | Some(_) => { heap.pop(); },
|
||||||
|
| ^^^^ second mutable borrow occurs here
|
||||||
|
...
|
||||||
|
LL | }
|
||||||
|
| - ... and the first borrow might be used here, when that temporary is dropped and runs the destructor for type `Option<PeekMut<'_, i32>>`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0499`.
|
Loading…
x
Reference in New Issue
Block a user