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:
Yuki Okushi 2021-06-17 21:56:44 +09:00 committed by GitHub
commit afe70ee440
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 8 deletions

View File

@ -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);

View File

@ -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 \

View 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() {}

View 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`.