Rollup merge of #104055 - AndyJado:bck_errors, r=davidtwco
Migrate diagnostics in `rustc_borrowck` sorry for making a new PR, [#103559](https://github.com/rust-lang/rust/pull/103559) and [#103960](https://github.com/rust-lang/rust/pull/103960). I am crawling, joyfully.
This commit is contained in:
commit
91fe117418
6 changed files with 612 additions and 252 deletions
|
@ -56,18 +56,6 @@ borrowck_returned_lifetime_short =
|
|||
borrowck_used_impl_require_static =
|
||||
the used `impl` has a `'static` requirement
|
||||
|
||||
borrowck_capture_kind_label =
|
||||
capture is {$kind_desc} because of use here
|
||||
|
||||
borrowck_var_borrow_by_use_place_in_generator =
|
||||
borrow occurs due to use of {$place} in closure in generator
|
||||
|
||||
borrowck_var_borrow_by_use_place_in_closure =
|
||||
borrow occurs due to use of {$place} in closure
|
||||
|
||||
borrowck_var_borrow_by_use_place =
|
||||
borrow occurs due to use of {$place}
|
||||
|
||||
borrowck_borrow_due_to_use_generator =
|
||||
borrow occurs due to use in generator
|
||||
|
||||
|
@ -101,12 +89,63 @@ borrowck_capture_mut =
|
|||
borrowck_capture_move =
|
||||
capture is moved because of use here
|
||||
|
||||
borrowck_var_borrow_by_use_place_in_generator =
|
||||
{$is_single_var ->
|
||||
*[true] borrow occurs
|
||||
[false] borrows occur
|
||||
} due to use of {$place} in generator
|
||||
|
||||
borrowck_var_borrow_by_use_place_in_closure =
|
||||
{$is_single_var ->
|
||||
*[true] borrow occurs
|
||||
[false] borrows occur
|
||||
} due to use of {$place} in closure
|
||||
|
||||
borrowck_var_borrow_by_use_in_generator =
|
||||
borrow occurs due to use in generator
|
||||
|
||||
borrowck_var_borrow_by_use_in_closure =
|
||||
borrow occurs due to use in closure
|
||||
|
||||
borrowck_var_move_by_use_place_in_generator =
|
||||
move occurs due to use of {$place} in generator
|
||||
|
||||
borrowck_var_move_by_use_place_in_closure =
|
||||
move occurs due to use of {$place} in closure
|
||||
|
||||
borrowck_var_move_by_use_in_generator =
|
||||
move occurs due to use in generator
|
||||
|
||||
borrowck_var_move_by_use_in_closure =
|
||||
move occurs due to use in closure
|
||||
|
||||
borrowck_partial_var_move_by_use_in_generator =
|
||||
variable {$is_partial ->
|
||||
[true] partially moved
|
||||
*[false] moved
|
||||
} due to use in generator
|
||||
|
||||
borrowck_partial_var_move_by_use_in_closure =
|
||||
variable {$is_partial ->
|
||||
[true] partially moved
|
||||
*[false] moved
|
||||
} due to use in closure
|
||||
|
||||
borrowck_var_first_borrow_by_use_place_in_generator =
|
||||
first borrow occurs due to use of {$place} in generator
|
||||
|
||||
borrowck_var_first_borrow_by_use_place_in_closure =
|
||||
first borrow occurs due to use of {$place} in closure
|
||||
|
||||
borrowck_var_second_borrow_by_use_place_in_generator =
|
||||
second borrow occurs due to use of {$place} in generator
|
||||
|
||||
borrowck_var_second_borrow_by_use_place_in_closure =
|
||||
second borrow occurs due to use of {$place} in closure
|
||||
|
||||
borrowck_var_mutable_borrow_by_use_place_in_closure =
|
||||
mutable borrow occurs due to use of {$place} in closure
|
||||
|
||||
borrowck_cannot_move_when_borrowed =
|
||||
cannot move out of {$place ->
|
||||
[value] value
|
||||
|
@ -127,3 +166,90 @@ borrowck_opaque_type_non_generic_param =
|
|||
[true] cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
|
||||
*[other] this generic parameter must be used with a generic {$kind} parameter
|
||||
}
|
||||
|
||||
borrowck_moved_due_to_call =
|
||||
{$place_name} {$is_partial ->
|
||||
[true] partially moved
|
||||
*[false] moved
|
||||
} due to this {$is_loop_message ->
|
||||
[true] call, in previous iteration of loop
|
||||
*[false] call
|
||||
}
|
||||
|
||||
borrowck_moved_due_to_usage_in_operator =
|
||||
{$place_name} {$is_partial ->
|
||||
[true] partially moved
|
||||
*[false] moved
|
||||
} due to usage in {$is_loop_message ->
|
||||
[true] operator, in previous iteration of loop
|
||||
*[false] operator
|
||||
}
|
||||
|
||||
borrowck_moved_due_to_implicit_into_iter_call =
|
||||
{$place_name} {$is_partial ->
|
||||
[true] partially moved
|
||||
*[false] moved
|
||||
} due to this implicit call to {$is_loop_message ->
|
||||
[true] `.into_iter()`, in previous iteration of loop
|
||||
*[false] `.into_iter()`
|
||||
}
|
||||
|
||||
borrowck_moved_due_to_method_call =
|
||||
{$place_name} {$is_partial ->
|
||||
[true] partially moved
|
||||
*[false] moved
|
||||
} due to this method {$is_loop_message ->
|
||||
[true] call, in previous iteration of loop
|
||||
*[false] call
|
||||
}
|
||||
|
||||
borrowck_value_moved_here =
|
||||
value {$is_partial ->
|
||||
[true] partially moved
|
||||
*[false] moved
|
||||
} {$is_move_msg ->
|
||||
[true] into closure here
|
||||
*[false] here
|
||||
}{$is_loop_message ->
|
||||
[true] , in previous iteration of loop
|
||||
*[false] {""}
|
||||
}
|
||||
|
||||
borrowck_consider_borrow_type_contents =
|
||||
help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
|
||||
|
||||
borrowck_moved_a_fn_once_in_call =
|
||||
this value implements `FnOnce`, which causes it to be moved when called
|
||||
|
||||
borrowck_calling_operator_moves_lhs =
|
||||
calling this operator moves the left-hand side
|
||||
|
||||
borrowck_func_take_self_moved_place =
|
||||
`{$func}` takes ownership of the receiver `self`, which moves {$place_name}
|
||||
|
||||
borrowck_suggest_iterate_over_slice =
|
||||
consider iterating over a slice of the `{$ty}`'s content to avoid moving into the `for` loop
|
||||
|
||||
borrowck_suggest_create_freash_reborrow =
|
||||
consider reborrowing the `Pin` instead of moving it
|
||||
|
||||
borrowck_value_capture_here =
|
||||
value captured {$is_within ->
|
||||
[true] here by generator
|
||||
*[false] here
|
||||
}
|
||||
|
||||
borrowck_move_out_place_here =
|
||||
{$place} is moved here
|
||||
|
||||
borrowck_closure_invoked_twice =
|
||||
closure cannot be invoked more than once because it moves the variable `{$place_name}` out of its environment
|
||||
|
||||
borrowck_closure_moved_twice =
|
||||
closure cannot be moved more than once as it is not `Copy` due to moving the variable `{$place_name}` out of its environment
|
||||
|
||||
borrowck_ty_no_impl_copy =
|
||||
{$is_partial_move ->
|
||||
[true] partial move
|
||||
*[false] move
|
||||
} occurs because {$place} has type `{$ty}`, which does not implement the `Copy` trait
|
||||
|
|
|
@ -30,8 +30,8 @@ use crate::borrow_set::TwoPhaseActivation;
|
|||
use crate::borrowck_errors;
|
||||
|
||||
use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead;
|
||||
use crate::diagnostics::find_all_local_uses;
|
||||
use crate::diagnostics::mutability_errors::mut_borrow_of_mutable_ref;
|
||||
use crate::diagnostics::{find_all_local_uses, CapturedMessageOpt};
|
||||
use crate::{
|
||||
borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf,
|
||||
InitializationRequiringAction, MirBorrowckCtxt, PrefixSet, WriteKind,
|
||||
|
@ -183,13 +183,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
let move_spans = self.move_spans(moved_place.as_ref(), move_out.source);
|
||||
let move_span = move_spans.args_or_use();
|
||||
|
||||
let move_msg = if move_spans.for_closure() { " into closure" } else { "" };
|
||||
let is_move_msg = move_spans.for_closure();
|
||||
|
||||
let loop_message = if location == move_out.source || move_site.traversed_back_edge {
|
||||
", in previous iteration of loop"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
let is_loop_message = location == move_out.source || move_site.traversed_back_edge;
|
||||
|
||||
if location == move_out.source {
|
||||
is_loop_move = true;
|
||||
|
@ -206,17 +202,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
let msg_opt = CapturedMessageOpt {
|
||||
is_partial_move,
|
||||
is_loop_message,
|
||||
is_move_msg,
|
||||
is_loop_move,
|
||||
maybe_reinitialized_locations_is_empty: maybe_reinitialized_locations
|
||||
.is_empty(),
|
||||
};
|
||||
self.explain_captures(
|
||||
&mut err,
|
||||
span,
|
||||
move_span,
|
||||
move_spans,
|
||||
*moved_place,
|
||||
partially_str,
|
||||
loop_message,
|
||||
move_msg,
|
||||
is_loop_move,
|
||||
maybe_reinitialized_locations.is_empty(),
|
||||
msg_opt,
|
||||
);
|
||||
}
|
||||
seen_spans.insert(move_span);
|
||||
|
@ -282,12 +282,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
if needs_note {
|
||||
let span = if let Some(local) = place.as_local() {
|
||||
Some(self.body.local_decls[local].source_info.span)
|
||||
if let Some(local) = place.as_local() {
|
||||
let span = self.body.local_decls[local].source_info.span;
|
||||
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
|
||||
is_partial_move,
|
||||
ty,
|
||||
place: ¬e_msg,
|
||||
span,
|
||||
});
|
||||
} else {
|
||||
None
|
||||
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Note {
|
||||
is_partial_move,
|
||||
ty,
|
||||
place: ¬e_msg,
|
||||
});
|
||||
};
|
||||
self.note_type_does_not_implement_copy(&mut err, ¬e_msg, ty, span, partial_str);
|
||||
}
|
||||
|
||||
if let UseSpans::FnSelfUse {
|
||||
|
@ -827,11 +836,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
|
||||
borrow_spans.var_path_only_subdiag(&mut err, crate::InitializationRequiringAction::Borrow);
|
||||
|
||||
move_spans.var_span_label(
|
||||
&mut err,
|
||||
format!("move occurs due to use{}", move_spans.describe()),
|
||||
"moved",
|
||||
);
|
||||
move_spans.var_subdiag(None, &mut err, None, |kind, var_span| {
|
||||
use crate::session_diagnostics::CaptureVarCause::*;
|
||||
match kind {
|
||||
Some(_) => MoveUseInGenerator { var_span },
|
||||
None => MoveUseInClosure { var_span },
|
||||
}
|
||||
});
|
||||
|
||||
self.explain_why_borrow_contains_point(location, borrow, None)
|
||||
.add_explanation_to_diagnostic(
|
||||
|
@ -868,13 +879,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
borrow_span,
|
||||
&self.describe_any_place(borrow.borrowed_place.as_ref()),
|
||||
);
|
||||
borrow_spans.var_subdiag(&mut err, Some(borrow.kind), |kind, var_span| {
|
||||
borrow_spans.var_subdiag(None, &mut err, Some(borrow.kind), |kind, var_span| {
|
||||
use crate::session_diagnostics::CaptureVarCause::*;
|
||||
let place = &borrow.borrowed_place;
|
||||
let desc_place = self.describe_any_place(place.as_ref());
|
||||
match kind {
|
||||
Some(_) => BorrowUsePlaceGenerator { place: desc_place, var_span },
|
||||
None => BorrowUsePlaceClosure { place: desc_place, var_span },
|
||||
Some(_) => {
|
||||
BorrowUsePlaceGenerator { place: desc_place, var_span, is_single_var: true }
|
||||
}
|
||||
None => BorrowUsePlaceClosure { place: desc_place, var_span, is_single_var: true },
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -988,16 +1001,26 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
immutable_section_description,
|
||||
"mutably borrow",
|
||||
);
|
||||
borrow_spans.var_span_label(
|
||||
borrow_spans.var_subdiag(
|
||||
None,
|
||||
&mut err,
|
||||
format!(
|
||||
"borrow occurs due to use of {}{}",
|
||||
desc_place,
|
||||
borrow_spans.describe(),
|
||||
),
|
||||
"immutable",
|
||||
Some(BorrowKind::Unique),
|
||||
|kind, var_span| {
|
||||
use crate::session_diagnostics::CaptureVarCause::*;
|
||||
match kind {
|
||||
Some(_) => BorrowUsePlaceGenerator {
|
||||
place: desc_place,
|
||||
var_span,
|
||||
is_single_var: true,
|
||||
},
|
||||
None => BorrowUsePlaceClosure {
|
||||
place: desc_place,
|
||||
var_span,
|
||||
is_single_var: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return err;
|
||||
} else {
|
||||
first_borrow_desc = "immutable ";
|
||||
|
@ -1070,32 +1093,48 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
};
|
||||
|
||||
if issued_spans == borrow_spans {
|
||||
borrow_spans.var_span_label(
|
||||
&mut err,
|
||||
format!("borrows occur due to use of {}{}", desc_place, borrow_spans.describe(),),
|
||||
gen_borrow_kind.describe_mutability(),
|
||||
);
|
||||
borrow_spans.var_subdiag(None, &mut err, Some(gen_borrow_kind), |kind, var_span| {
|
||||
use crate::session_diagnostics::CaptureVarCause::*;
|
||||
match kind {
|
||||
Some(_) => BorrowUsePlaceGenerator {
|
||||
place: desc_place,
|
||||
var_span,
|
||||
is_single_var: false,
|
||||
},
|
||||
None => {
|
||||
BorrowUsePlaceClosure { place: desc_place, var_span, is_single_var: false }
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
let borrow_place = &issued_borrow.borrowed_place;
|
||||
let borrow_place_desc = self.describe_any_place(borrow_place.as_ref());
|
||||
issued_spans.var_span_label(
|
||||
issued_spans.var_subdiag(
|
||||
Some(&self.infcx.tcx.sess.parse_sess.span_diagnostic),
|
||||
&mut err,
|
||||
format!(
|
||||
"first borrow occurs due to use of {}{}",
|
||||
borrow_place_desc,
|
||||
issued_spans.describe(),
|
||||
),
|
||||
issued_borrow.kind.describe_mutability(),
|
||||
Some(issued_borrow.kind),
|
||||
|kind, var_span| {
|
||||
use crate::session_diagnostics::CaptureVarCause::*;
|
||||
let borrow_place = &issued_borrow.borrowed_place;
|
||||
let borrow_place_desc = self.describe_any_place(borrow_place.as_ref());
|
||||
match kind {
|
||||
Some(_) => {
|
||||
FirstBorrowUsePlaceGenerator { place: borrow_place_desc, var_span }
|
||||
}
|
||||
None => FirstBorrowUsePlaceClosure { place: borrow_place_desc, var_span },
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
borrow_spans.var_span_label(
|
||||
borrow_spans.var_subdiag(
|
||||
Some(&self.infcx.tcx.sess.parse_sess.span_diagnostic),
|
||||
&mut err,
|
||||
format!(
|
||||
"second borrow occurs due to use of {}{}",
|
||||
desc_place,
|
||||
borrow_spans.describe(),
|
||||
),
|
||||
gen_borrow_kind.describe_mutability(),
|
||||
Some(gen_borrow_kind),
|
||||
|kind, var_span| {
|
||||
use crate::session_diagnostics::CaptureVarCause::*;
|
||||
match kind {
|
||||
Some(_) => SecondBorrowUsePlaceGenerator { place: desc_place, var_span },
|
||||
None => SecondBorrowUsePlaceClosure { place: desc_place, var_span },
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1731,9 +1770,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
err.span_label(borrow_span, "borrowed value does not live long enough");
|
||||
err.span_label(drop_span, format!("`{}` dropped here while still borrowed", name));
|
||||
|
||||
let within = if borrow_spans.for_generator() { " by generator" } else { "" };
|
||||
|
||||
borrow_spans.args_span_label(&mut err, format!("value captured here{}", within));
|
||||
borrow_spans.args_subdiag(&mut err, |args_span| {
|
||||
crate::session_diagnostics::CaptureArgLabel::Capture {
|
||||
is_within: borrow_spans.for_generator(),
|
||||
args_span,
|
||||
}
|
||||
});
|
||||
|
||||
explanation.add_explanation_to_diagnostic(
|
||||
self.infcx.tcx,
|
||||
|
@ -1947,9 +1989,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
None,
|
||||
);
|
||||
|
||||
let within = if borrow_spans.for_generator() { " by generator" } else { "" };
|
||||
|
||||
borrow_spans.args_span_label(&mut err, format!("value captured here{}", within));
|
||||
borrow_spans.args_subdiag(&mut err, |args_span| {
|
||||
crate::session_diagnostics::CaptureArgLabel::Capture {
|
||||
is_within: borrow_spans.for_generator(),
|
||||
args_span,
|
||||
}
|
||||
});
|
||||
|
||||
err
|
||||
}
|
||||
|
@ -2382,11 +2427,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
section,
|
||||
"assign",
|
||||
);
|
||||
loan_spans.var_span_label(
|
||||
&mut err,
|
||||
format!("borrow occurs due to use{}", loan_spans.describe()),
|
||||
loan.kind.describe_mutability(),
|
||||
);
|
||||
|
||||
loan_spans.var_subdiag(None, &mut err, Some(loan.kind), |kind, var_span| {
|
||||
use crate::session_diagnostics::CaptureVarCause::*;
|
||||
match kind {
|
||||
Some(_) => BorrowUseInGenerator { var_span },
|
||||
None => BorrowUseInClosure { var_span },
|
||||
}
|
||||
});
|
||||
|
||||
self.buffer_error(err);
|
||||
|
||||
|
@ -2396,11 +2444,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
|
||||
let mut err = self.cannot_assign_to_borrowed(span, loan_span, &descr_place);
|
||||
|
||||
loan_spans.var_span_label(
|
||||
&mut err,
|
||||
format!("borrow occurs due to use{}", loan_spans.describe()),
|
||||
loan.kind.describe_mutability(),
|
||||
);
|
||||
loan_spans.var_subdiag(None, &mut err, Some(loan.kind), |kind, var_span| {
|
||||
use crate::session_diagnostics::CaptureVarCause::*;
|
||||
match kind {
|
||||
Some(_) => BorrowUseInGenerator { var_span },
|
||||
None => BorrowUseInClosure { var_span },
|
||||
}
|
||||
});
|
||||
|
||||
self.explain_why_borrow_contains_point(location, loan, None).add_explanation_to_diagnostic(
|
||||
self.infcx.tcx,
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
//! Borrow checker diagnostics.
|
||||
|
||||
use crate::session_diagnostics::{
|
||||
CaptureArgLabel, CaptureReasonLabel, CaptureReasonNote, CaptureReasonSuggest, CaptureVarCause,
|
||||
CaptureVarKind, CaptureVarPathUseCause, OnClosureNote,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use rustc_errors::{Applicability, Diagnostic};
|
||||
use rustc_hir as hir;
|
||||
|
@ -117,13 +121,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
if let ty::Closure(did, _) = self.body.local_decls[closure].ty.kind() {
|
||||
let did = did.expect_local();
|
||||
if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) {
|
||||
diag.span_note(
|
||||
*span,
|
||||
&format!(
|
||||
"closure cannot be invoked more than once because it moves the \
|
||||
variable `{}` out of its environment",
|
||||
ty::place_to_string_for_capture(self.infcx.tcx, hir_place)
|
||||
),
|
||||
diag.eager_subdiagnostic(
|
||||
&self.infcx.tcx.sess.parse_sess.span_diagnostic,
|
||||
OnClosureNote::InvokedTwice {
|
||||
place_name: &ty::place_to_string_for_capture(
|
||||
self.infcx.tcx,
|
||||
hir_place,
|
||||
),
|
||||
span: *span,
|
||||
},
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
@ -137,13 +143,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
if let ty::Closure(did, _) = self.body.local_decls[target].ty.kind() {
|
||||
let did = did.expect_local();
|
||||
if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) {
|
||||
diag.span_note(
|
||||
*span,
|
||||
&format!(
|
||||
"closure cannot be moved more than once as it is not `Copy` due to \
|
||||
moving the variable `{}` out of its environment",
|
||||
ty::place_to_string_for_capture(self.infcx.tcx, hir_place)
|
||||
),
|
||||
diag.eager_subdiagnostic(
|
||||
&self.infcx.tcx.sess.parse_sess.span_diagnostic,
|
||||
OnClosureNote::MovedTwice {
|
||||
place_name: &ty::place_to_string_for_capture(self.infcx.tcx, hir_place),
|
||||
span: *span,
|
||||
},
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
@ -380,25 +385,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Add a note that a type does not implement `Copy`
|
||||
pub(super) fn note_type_does_not_implement_copy(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
place_desc: &str,
|
||||
ty: Ty<'tcx>,
|
||||
span: Option<Span>,
|
||||
move_prefix: &str,
|
||||
) {
|
||||
let message = format!(
|
||||
"{move_prefix}move occurs because {place_desc} has type `{ty}`, which does not implement the `Copy` trait",
|
||||
);
|
||||
if let Some(span) = span {
|
||||
err.span_label(span, message);
|
||||
} else {
|
||||
err.note(&message);
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn borrowed_content_source(
|
||||
&self,
|
||||
deref_base: PlaceRef<'tcx>,
|
||||
|
@ -582,9 +568,13 @@ impl UseSpans<'_> {
|
|||
}
|
||||
|
||||
/// Add a span label to the arguments of the closure, if it exists.
|
||||
pub(super) fn args_span_label(self, err: &mut Diagnostic, message: impl Into<String>) {
|
||||
pub(super) fn args_subdiag(
|
||||
self,
|
||||
err: &mut Diagnostic,
|
||||
f: impl FnOnce(Span) -> CaptureArgLabel,
|
||||
) {
|
||||
if let UseSpans::ClosureUse { args_span, .. } = self {
|
||||
err.span_label(args_span, message);
|
||||
err.subdiagnostic(f(args_span));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -595,8 +585,8 @@ impl UseSpans<'_> {
|
|||
err: &mut Diagnostic,
|
||||
action: crate::InitializationRequiringAction,
|
||||
) {
|
||||
use crate::session_diagnostics::CaptureVarPathUseCause::*;
|
||||
use crate::InitializationRequiringAction::*;
|
||||
use CaptureVarPathUseCause::*;
|
||||
if let UseSpans::ClosureUse { generator_kind, path_span, .. } = self {
|
||||
match generator_kind {
|
||||
Some(_) => {
|
||||
|
@ -619,34 +609,14 @@ impl UseSpans<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Add a span label to the use of the captured variable, if it exists.
|
||||
pub(super) fn var_span_label(
|
||||
self,
|
||||
err: &mut Diagnostic,
|
||||
message: impl Into<String>,
|
||||
kind_desc: impl Into<String>,
|
||||
) {
|
||||
if let UseSpans::ClosureUse { capture_kind_span, path_span, .. } = self {
|
||||
if capture_kind_span == path_span {
|
||||
err.span_label(capture_kind_span, message);
|
||||
} else {
|
||||
let capture_kind_label =
|
||||
format!("capture is {} because of use here", kind_desc.into());
|
||||
let path_label = message;
|
||||
err.span_label(capture_kind_span, capture_kind_label);
|
||||
err.span_label(path_span, path_label);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a subdiagnostic to the use of the captured variable, if it exists.
|
||||
pub(super) fn var_subdiag(
|
||||
self,
|
||||
handler: Option<&rustc_errors::Handler>,
|
||||
err: &mut Diagnostic,
|
||||
kind: Option<rustc_middle::mir::BorrowKind>,
|
||||
f: impl Fn(Option<GeneratorKind>, Span) -> crate::session_diagnostics::CaptureVarCause,
|
||||
f: impl FnOnce(Option<GeneratorKind>, Span) -> CaptureVarCause,
|
||||
) {
|
||||
use crate::session_diagnostics::CaptureVarKind::*;
|
||||
if let UseSpans::ClosureUse { generator_kind, capture_kind_span, path_span, .. } = self {
|
||||
if capture_kind_span != path_span {
|
||||
err.subdiagnostic(match kind {
|
||||
|
@ -654,17 +624,21 @@ impl UseSpans<'_> {
|
|||
rustc_middle::mir::BorrowKind::Shared
|
||||
| rustc_middle::mir::BorrowKind::Shallow
|
||||
| rustc_middle::mir::BorrowKind::Unique => {
|
||||
Immute { kind_span: capture_kind_span }
|
||||
CaptureVarKind::Immut { kind_span: capture_kind_span }
|
||||
}
|
||||
|
||||
rustc_middle::mir::BorrowKind::Mut { .. } => {
|
||||
Mut { kind_span: capture_kind_span }
|
||||
CaptureVarKind::Mut { kind_span: capture_kind_span }
|
||||
}
|
||||
},
|
||||
None => Move { kind_span: capture_kind_span },
|
||||
None => CaptureVarKind::Move { kind_span: capture_kind_span },
|
||||
});
|
||||
};
|
||||
err.subdiagnostic(f(generator_kind, path_span));
|
||||
let diag = f(generator_kind, path_span);
|
||||
match handler {
|
||||
Some(hd) => err.eager_subdiagnostic(hd, diag),
|
||||
None => err.subdiagnostic(diag),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -684,20 +658,6 @@ impl UseSpans<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Describe the span associated with a use of a place.
|
||||
pub(super) fn describe(&self) -> &str {
|
||||
match *self {
|
||||
UseSpans::ClosureUse { generator_kind, .. } => {
|
||||
if generator_kind.is_some() {
|
||||
" in generator"
|
||||
} else {
|
||||
" in closure"
|
||||
}
|
||||
}
|
||||
_ => "",
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn or_else<F>(self, if_other: F) -> Self
|
||||
where
|
||||
F: FnOnce() -> Self,
|
||||
|
@ -788,6 +748,15 @@ impl<'tcx> BorrowedContentSource<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
///helper struct for explain_captures()
|
||||
struct CapturedMessageOpt {
|
||||
is_partial_move: bool,
|
||||
is_loop_message: bool,
|
||||
is_move_msg: bool,
|
||||
is_loop_move: bool,
|
||||
maybe_reinitialized_locations_is_empty: bool,
|
||||
}
|
||||
|
||||
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
/// Finds the spans associated to a move or copy of move_place at location.
|
||||
pub(super) fn move_spans(
|
||||
|
@ -1027,12 +996,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
move_span: Span,
|
||||
move_spans: UseSpans<'tcx>,
|
||||
moved_place: Place<'tcx>,
|
||||
partially_str: &str,
|
||||
loop_message: &str,
|
||||
move_msg: &str,
|
||||
is_loop_move: bool,
|
||||
maybe_reinitialized_locations_is_empty: bool,
|
||||
msg_opt: CapturedMessageOpt,
|
||||
) {
|
||||
let CapturedMessageOpt {
|
||||
is_partial_move: is_partial,
|
||||
is_loop_message,
|
||||
is_move_msg,
|
||||
is_loop_move,
|
||||
maybe_reinitialized_locations_is_empty,
|
||||
} = msg_opt;
|
||||
if let UseSpans::FnSelfUse { var_span, fn_call_span, fn_span, kind } = move_spans {
|
||||
let place_name = self
|
||||
.describe_place(moved_place.as_ref())
|
||||
|
@ -1042,30 +1014,26 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
CallKind::FnCall { fn_trait_id, .. }
|
||||
if Some(fn_trait_id) == self.infcx.tcx.lang_items().fn_once_trait() =>
|
||||
{
|
||||
err.span_label(
|
||||
err.subdiagnostic(CaptureReasonLabel::Call {
|
||||
fn_call_span,
|
||||
&format!(
|
||||
"{place_name} {partially_str}moved due to this call{loop_message}",
|
||||
),
|
||||
);
|
||||
err.span_note(
|
||||
var_span,
|
||||
"this value implements `FnOnce`, which causes it to be moved when called",
|
||||
);
|
||||
place_name: &place_name,
|
||||
is_partial,
|
||||
is_loop_message,
|
||||
});
|
||||
err.subdiagnostic(CaptureReasonNote::FnOnceMoveInCall { var_span });
|
||||
}
|
||||
CallKind::Operator { self_arg, .. } => {
|
||||
let self_arg = self_arg.unwrap();
|
||||
err.span_label(
|
||||
err.subdiagnostic(CaptureReasonLabel::OperatorUse {
|
||||
fn_call_span,
|
||||
&format!(
|
||||
"{place_name} {partially_str}moved due to usage in operator{loop_message}",
|
||||
),
|
||||
);
|
||||
place_name: &place_name,
|
||||
is_partial,
|
||||
is_loop_message,
|
||||
});
|
||||
if self.fn_self_span_reported.insert(fn_span) {
|
||||
err.span_note(
|
||||
self_arg.span,
|
||||
"calling this operator moves the left-hand side",
|
||||
);
|
||||
err.subdiagnostic(CaptureReasonNote::LhsMoveByOperator {
|
||||
span: self_arg.span,
|
||||
});
|
||||
}
|
||||
}
|
||||
CallKind::Normal { self_arg, desugaring, method_did, method_substs } => {
|
||||
|
@ -1086,23 +1054,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
_ => false,
|
||||
};
|
||||
if suggest {
|
||||
err.span_suggestion_verbose(
|
||||
move_span.shrink_to_lo(),
|
||||
&format!(
|
||||
"consider iterating over a slice of the `{ty}`'s content to \
|
||||
avoid moving into the `for` loop",
|
||||
),
|
||||
"&",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.subdiagnostic(CaptureReasonSuggest::IterateSlice {
|
||||
ty,
|
||||
span: move_span.shrink_to_lo(),
|
||||
});
|
||||
}
|
||||
|
||||
err.span_label(
|
||||
err.subdiagnostic(CaptureReasonLabel::ImplicitCall {
|
||||
fn_call_span,
|
||||
&format!(
|
||||
"{place_name} {partially_str}moved due to this implicit call to `.into_iter()`{loop_message}",
|
||||
),
|
||||
);
|
||||
place_name: &place_name,
|
||||
is_partial,
|
||||
is_loop_message,
|
||||
});
|
||||
// If the moved place was a `&mut` ref, then we can
|
||||
// suggest to reborrow it where it was moved, so it
|
||||
// will still be valid by the time we get to the usage.
|
||||
|
@ -1125,13 +1088,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
err.span_label(
|
||||
err.subdiagnostic(CaptureReasonLabel::MethodCall {
|
||||
fn_call_span,
|
||||
&format!(
|
||||
"{place_name} {partially_str}moved due to this method call{loop_message}",
|
||||
),
|
||||
);
|
||||
|
||||
place_name: &place_name,
|
||||
is_partial,
|
||||
is_loop_message,
|
||||
});
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
// Erase and shadow everything that could be passed to the new infcx.
|
||||
let ty = tcx.erase_regions(moved_place.ty(self.body, tcx).ty);
|
||||
|
@ -1147,12 +1109,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
)
|
||||
&& infcx.can_eq(self.param_env, ty, self_ty)
|
||||
{
|
||||
err.span_suggestion_verbose(
|
||||
fn_call_span.shrink_to_lo(),
|
||||
"consider reborrowing the `Pin` instead of moving it",
|
||||
"as_mut().".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.eager_subdiagnostic(
|
||||
&self.infcx.tcx.sess.parse_sess.span_diagnostic,
|
||||
CaptureReasonSuggest::FreshReborrow {
|
||||
span: fn_call_span.shrink_to_lo(),
|
||||
});
|
||||
}
|
||||
if let Some(clone_trait) = tcx.lang_items().clone_trait()
|
||||
&& let trait_ref = tcx.mk_trait_ref(clone_trait, [ty])
|
||||
|
@ -1177,10 +1138,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
// error messages.
|
||||
if span != DUMMY_SP && self.fn_self_span_reported.insert(self_arg.span) {
|
||||
let func = tcx.def_path_str(method_did);
|
||||
err.span_note(
|
||||
self_arg.span,
|
||||
&format!("`{func}` takes ownership of the receiver `self`, which moves {place_name}")
|
||||
);
|
||||
err.subdiagnostic(CaptureReasonNote::FuncTakeSelf {
|
||||
func,
|
||||
place_name,
|
||||
span: self_arg.span,
|
||||
});
|
||||
}
|
||||
let parent_did = tcx.parent(method_did);
|
||||
let parent_self_ty =
|
||||
|
@ -1194,30 +1156,28 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result))
|
||||
});
|
||||
if is_option_or_result && maybe_reinitialized_locations_is_empty {
|
||||
err.span_label(
|
||||
var_span,
|
||||
"help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents",
|
||||
);
|
||||
err.subdiagnostic(CaptureReasonLabel::BorrowContent { var_span });
|
||||
}
|
||||
}
|
||||
// Other desugarings takes &self, which cannot cause a move
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
if move_span != span || !loop_message.is_empty() {
|
||||
err.span_label(
|
||||
if move_span != span || is_loop_message {
|
||||
err.subdiagnostic(CaptureReasonLabel::MovedHere {
|
||||
move_span,
|
||||
format!("value {partially_str}moved{move_msg} here{loop_message}"),
|
||||
);
|
||||
is_partial,
|
||||
is_move_msg,
|
||||
is_loop_message,
|
||||
});
|
||||
}
|
||||
// If the move error occurs due to a loop, don't show
|
||||
// another message for the same span
|
||||
if loop_message.is_empty() {
|
||||
move_spans.var_span_label(
|
||||
err,
|
||||
format!("variable {partially_str}moved due to use{}", move_spans.describe()),
|
||||
"moved",
|
||||
);
|
||||
if !is_loop_message {
|
||||
move_spans.var_subdiag(None, err, None, |kind, var_span| match kind {
|
||||
Some(_) => CaptureVarCause::PartialMoveUseInGenerator { var_span, is_partial },
|
||||
None => CaptureVarCause::PartialMoveUseInClosure { var_span, is_partial },
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ use rustc_mir_dataflow::move_paths::{
|
|||
};
|
||||
use rustc_span::{BytePos, Span};
|
||||
|
||||
use crate::diagnostics::CapturedMessageOpt;
|
||||
use crate::diagnostics::{DescribePlaceOpt, UseSpans};
|
||||
use crate::prefixes::PrefixSet;
|
||||
use crate::MirBorrowckCtxt;
|
||||
|
@ -397,10 +398,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
};
|
||||
let msg_opt = CapturedMessageOpt {
|
||||
is_partial_move: false,
|
||||
is_loop_message: false,
|
||||
is_move_msg: false,
|
||||
is_loop_move: false,
|
||||
maybe_reinitialized_locations_is_empty: true,
|
||||
};
|
||||
if let Some(use_spans) = use_spans {
|
||||
self.explain_captures(
|
||||
&mut err, span, span, use_spans, move_place, "", "", "", false, true,
|
||||
);
|
||||
self.explain_captures(&mut err, span, span, use_spans, move_place, msg_opt);
|
||||
}
|
||||
err
|
||||
}
|
||||
|
@ -416,13 +422,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
None => "value".to_string(),
|
||||
};
|
||||
|
||||
self.note_type_does_not_implement_copy(
|
||||
err,
|
||||
&place_desc,
|
||||
place_ty,
|
||||
Some(span),
|
||||
"",
|
||||
);
|
||||
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
|
||||
is_partial_move: false,
|
||||
ty: place_ty,
|
||||
place: &place_desc,
|
||||
span,
|
||||
});
|
||||
} else {
|
||||
binds_to.sort();
|
||||
binds_to.dedup();
|
||||
|
@ -444,9 +449,19 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
Some(desc) => format!("`{desc}`"),
|
||||
None => "value".to_string(),
|
||||
};
|
||||
self.note_type_does_not_implement_copy(err, &place_desc, place_ty, Some(span), "");
|
||||
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
|
||||
is_partial_move: false,
|
||||
ty: place_ty,
|
||||
place: &place_desc,
|
||||
span,
|
||||
});
|
||||
|
||||
use_spans.args_span_label(err, format!("{place_desc} is moved here"));
|
||||
use_spans.args_subdiag(err, |args_span| {
|
||||
crate::session_diagnostics::CaptureArgLabel::MoveOutPlace {
|
||||
place: place_desc,
|
||||
args_span,
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -534,13 +549,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
if binds_to.len() == 1 {
|
||||
self.note_type_does_not_implement_copy(
|
||||
err,
|
||||
&format!("`{}`", self.local_names[*local].unwrap()),
|
||||
bind_to.ty,
|
||||
Some(binding_span),
|
||||
"",
|
||||
);
|
||||
let place_desc = &format!("`{}`", self.local_names[*local].unwrap());
|
||||
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
|
||||
is_partial_move: false,
|
||||
ty: bind_to.ty,
|
||||
place: &place_desc,
|
||||
span: binding_span,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -231,14 +231,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
if suggest {
|
||||
borrow_spans.var_span_label(
|
||||
&mut err,
|
||||
format!(
|
||||
"mutable borrow occurs due to use of {} in closure",
|
||||
self.describe_any_place(access_place.as_ref()),
|
||||
),
|
||||
"mutable",
|
||||
);
|
||||
borrow_spans.var_subdiag(
|
||||
None,
|
||||
&mut err,
|
||||
Some(mir::BorrowKind::Mut { allow_two_phase_borrow: false }),
|
||||
|_kind, var_span| {
|
||||
let place = self.describe_any_place(access_place.as_ref());
|
||||
crate::session_diagnostics::CaptureVarCause::MutableBorrowUsePlaceClosure {
|
||||
place,
|
||||
var_span,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
borrow_span
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ pub(crate) enum CaptureVarPathUseCause {
|
|||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum CaptureVarKind {
|
||||
#[label(borrowck_capture_immute)]
|
||||
Immute {
|
||||
Immut {
|
||||
#[primary_span]
|
||||
kind_span: Span,
|
||||
},
|
||||
|
@ -204,16 +204,80 @@ pub(crate) enum CaptureVarKind {
|
|||
pub(crate) enum CaptureVarCause {
|
||||
#[label(borrowck_var_borrow_by_use_place_in_generator)]
|
||||
BorrowUsePlaceGenerator {
|
||||
is_single_var: bool,
|
||||
place: String,
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
},
|
||||
#[label(borrowck_var_borrow_by_use_place_in_closure)]
|
||||
BorrowUsePlaceClosure {
|
||||
is_single_var: bool,
|
||||
place: String,
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
},
|
||||
#[label(borrowck_var_borrow_by_use_in_generator)]
|
||||
BorrowUseInGenerator {
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
},
|
||||
#[label(borrowck_var_borrow_by_use_in_closure)]
|
||||
BorrowUseInClosure {
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
},
|
||||
#[label(borrowck_var_move_by_use_in_generator)]
|
||||
MoveUseInGenerator {
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
},
|
||||
#[label(borrowck_var_move_by_use_in_closure)]
|
||||
MoveUseInClosure {
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
},
|
||||
#[label(borrowck_var_first_borrow_by_use_place_in_generator)]
|
||||
FirstBorrowUsePlaceGenerator {
|
||||
place: String,
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
},
|
||||
#[label(borrowck_var_first_borrow_by_use_place_in_closure)]
|
||||
FirstBorrowUsePlaceClosure {
|
||||
place: String,
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
},
|
||||
#[label(borrowck_var_second_borrow_by_use_place_in_generator)]
|
||||
SecondBorrowUsePlaceGenerator {
|
||||
place: String,
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
},
|
||||
#[label(borrowck_var_second_borrow_by_use_place_in_closure)]
|
||||
SecondBorrowUsePlaceClosure {
|
||||
place: String,
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
},
|
||||
#[label(borrowck_var_mutable_borrow_by_use_place_in_closure)]
|
||||
MutableBorrowUsePlaceClosure {
|
||||
place: String,
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
},
|
||||
#[label(borrowck_partial_var_move_by_use_in_generator)]
|
||||
PartialMoveUseInGenerator {
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
is_partial: bool,
|
||||
},
|
||||
#[label(borrowck_partial_var_move_by_use_in_closure)]
|
||||
PartialMoveUseInClosure {
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
is_partial: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -239,3 +303,144 @@ pub(crate) struct NonGenericOpaqueTypeParam<'a, 'tcx> {
|
|||
#[label]
|
||||
pub param_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum CaptureReasonLabel<'a> {
|
||||
#[label(borrowck_moved_due_to_call)]
|
||||
Call {
|
||||
#[primary_span]
|
||||
fn_call_span: Span,
|
||||
place_name: &'a str,
|
||||
is_partial: bool,
|
||||
is_loop_message: bool,
|
||||
},
|
||||
#[label(borrowck_moved_due_to_usage_in_operator)]
|
||||
OperatorUse {
|
||||
#[primary_span]
|
||||
fn_call_span: Span,
|
||||
place_name: &'a str,
|
||||
is_partial: bool,
|
||||
is_loop_message: bool,
|
||||
},
|
||||
#[label(borrowck_moved_due_to_implicit_into_iter_call)]
|
||||
ImplicitCall {
|
||||
#[primary_span]
|
||||
fn_call_span: Span,
|
||||
place_name: &'a str,
|
||||
is_partial: bool,
|
||||
is_loop_message: bool,
|
||||
},
|
||||
#[label(borrowck_moved_due_to_method_call)]
|
||||
MethodCall {
|
||||
#[primary_span]
|
||||
fn_call_span: Span,
|
||||
place_name: &'a str,
|
||||
is_partial: bool,
|
||||
is_loop_message: bool,
|
||||
},
|
||||
#[label(borrowck_value_moved_here)]
|
||||
MovedHere {
|
||||
#[primary_span]
|
||||
move_span: Span,
|
||||
is_partial: bool,
|
||||
is_move_msg: bool,
|
||||
is_loop_message: bool,
|
||||
},
|
||||
#[label(borrowck_consider_borrow_type_contents)]
|
||||
BorrowContent {
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum CaptureReasonNote {
|
||||
#[note(borrowck_moved_a_fn_once_in_call)]
|
||||
FnOnceMoveInCall {
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
},
|
||||
#[note(borrowck_calling_operator_moves_lhs)]
|
||||
LhsMoveByOperator {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[note(borrowck_func_take_self_moved_place)]
|
||||
FuncTakeSelf {
|
||||
func: String,
|
||||
place_name: String,
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum CaptureReasonSuggest<'tcx> {
|
||||
#[suggestion(
|
||||
borrowck_suggest_iterate_over_slice,
|
||||
applicability = "maybe-incorrect",
|
||||
code = "&",
|
||||
style = "verbose"
|
||||
)]
|
||||
IterateSlice {
|
||||
ty: Ty<'tcx>,
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[suggestion(
|
||||
borrowck_suggest_create_freash_reborrow,
|
||||
applicability = "maybe-incorrect",
|
||||
code = "as_mut().",
|
||||
style = "verbose"
|
||||
)]
|
||||
FreshReborrow {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum CaptureArgLabel {
|
||||
#[label(borrowck_value_capture_here)]
|
||||
Capture {
|
||||
is_within: bool,
|
||||
#[primary_span]
|
||||
args_span: Span,
|
||||
},
|
||||
#[label(borrowck_move_out_place_here)]
|
||||
MoveOutPlace {
|
||||
place: String,
|
||||
#[primary_span]
|
||||
args_span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum OnClosureNote<'a> {
|
||||
#[note(borrowck_closure_invoked_twice)]
|
||||
InvokedTwice {
|
||||
place_name: &'a str,
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[note(borrowck_closure_moved_twice)]
|
||||
MovedTwice {
|
||||
place_name: &'a str,
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum TypeNoCopy<'a, 'tcx> {
|
||||
#[label(borrowck_ty_no_impl_copy)]
|
||||
Label {
|
||||
is_partial_move: bool,
|
||||
ty: Ty<'tcx>,
|
||||
place: &'a str,
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[note(borrowck_ty_no_impl_copy)]
|
||||
Note { is_partial_move: bool, ty: Ty<'tcx>, place: &'a str },
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue