未验证 提交 c8a8a23a 编写于 作者: Y Yuki Okushi

Do not emit invalid suggestions on multiple mutable borrow errors

上级 607d6b00
......@@ -453,6 +453,7 @@ pub(in crate::borrow_check) fn report_move_out_while_borrowed(
&mut err,
"",
Some(borrow_span),
None,
);
err.buffer(&mut self.errors_buffer);
}
......@@ -498,6 +499,7 @@ pub(in crate::borrow_check) fn report_use_while_mutably_borrowed(
&mut err,
"",
None,
None,
);
err
}
......@@ -718,6 +720,7 @@ pub(in crate::borrow_check) fn report_conflicting_borrow(
&mut err,
first_borrow_desc,
None,
Some((issued_span, span)),
);
err
......@@ -1076,6 +1079,7 @@ fn report_local_value_does_not_live_long_enough(
&mut err,
"",
None,
None,
);
}
} else {
......@@ -1093,6 +1097,7 @@ fn report_local_value_does_not_live_long_enough(
&mut err,
"",
None,
None,
);
}
......@@ -1158,6 +1163,7 @@ fn report_borrow_conflicts_with_destructor(
&mut err,
"",
None,
None,
);
err.buffer(&mut self.errors_buffer);
......@@ -1236,6 +1242,7 @@ fn report_temporary_value_does_not_live_long_enough(
&mut err,
"",
None,
None,
);
let within = if borrow_spans.for_generator() { " by generator" } else { "" };
......@@ -1614,6 +1621,7 @@ pub(in crate::borrow_check) fn report_illegal_mutation_of_borrowed(
&mut err,
"",
None,
None,
);
self.explain_deref_coercion(loan, &mut err);
......
......@@ -66,6 +66,7 @@ pub(in crate::borrow_check) fn add_explanation_to_diagnostic<'tcx>(
err: &mut DiagnosticBuilder<'_>,
borrow_desc: &str,
borrow_span: Option<Span>,
multiple_borrow_span: Option<(Span, Span)>,
) {
match *self {
BorrowExplanation::UsedLater(later_use_kind, var_or_use_span, path_span) => {
......@@ -192,14 +193,23 @@ pub(in crate::borrow_check) fn add_explanation_to_diagnostic<'tcx>(
if let Some(info) = &local_decl.is_block_tail {
if info.tail_result_is_ignored {
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,
);
// #85581: If the first mutable borrow's scope contains
// the second borrow, this suggestion isn't helpful.
if !multiple_borrow_span
.map(|(old, new)| {
old.to(info.span.shrink_to_hi()).contains(new)
})
.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 {
err.note(
"the temporary is part of an expression at the end of a \
......
// 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() {}
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`.
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册