Auto merge of #94515 - estebank:tweak-move-error, r=davidtwco
Tweak move error Point at method definition that causes type to be consumed. Fix #94056.
This commit is contained in:
commit
10dccdc7fc
21 changed files with 289 additions and 242 deletions
|
@ -1,5 +1,5 @@
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use rustc_const_eval::util::{CallDesugaringKind, CallKind};
|
use rustc_const_eval::util::CallKind;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
|
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
@ -17,7 +17,7 @@ use rustc_middle::ty::{
|
||||||
};
|
};
|
||||||
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
|
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
|
use rustc_span::{BytePos, MultiSpan, Span};
|
||||||
use rustc_trait_selection::infer::InferCtxtExt;
|
use rustc_trait_selection::infer::InferCtxtExt;
|
||||||
use rustc_trait_selection::traits::TraitEngineExt as _;
|
use rustc_trait_selection::traits::TraitEngineExt as _;
|
||||||
|
|
||||||
|
@ -195,144 +195,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
is_loop_move = true;
|
is_loop_move = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let UseSpans::FnSelfUse { var_span, fn_call_span, fn_span, kind } = move_spans {
|
self.explain_captures(
|
||||||
let place_name = self
|
&mut err,
|
||||||
.describe_place(moved_place.as_ref())
|
span,
|
||||||
.map(|n| format!("`{}`", n))
|
move_span,
|
||||||
.unwrap_or_else(|| "value".to_owned());
|
move_spans,
|
||||||
match kind {
|
*moved_place,
|
||||||
CallKind::FnCall { fn_trait_id, .. }
|
Some(used_place),
|
||||||
if Some(fn_trait_id) == self.infcx.tcx.lang_items().fn_once_trait() =>
|
partially_str,
|
||||||
{
|
loop_message,
|
||||||
err.span_label(
|
move_msg,
|
||||||
fn_call_span,
|
is_loop_move,
|
||||||
&format!(
|
maybe_reinitialized_locations.is_empty(),
|
||||||
"{} {}moved due to this call{}",
|
);
|
||||||
place_name, partially_str, loop_message
|
|
||||||
),
|
|
||||||
);
|
|
||||||
err.span_note(
|
|
||||||
var_span,
|
|
||||||
"this value implements `FnOnce`, which causes it to be moved when called",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
CallKind::Operator { self_arg, .. } => {
|
|
||||||
let self_arg = self_arg.unwrap();
|
|
||||||
err.span_label(
|
|
||||||
fn_call_span,
|
|
||||||
&format!(
|
|
||||||
"{} {}moved due to usage in operator{}",
|
|
||||||
place_name, partially_str, loop_message
|
|
||||||
),
|
|
||||||
);
|
|
||||||
if self.fn_self_span_reported.insert(fn_span) {
|
|
||||||
err.span_note(
|
|
||||||
// Check whether the source is accessible
|
|
||||||
if self
|
|
||||||
.infcx
|
|
||||||
.tcx
|
|
||||||
.sess
|
|
||||||
.source_map()
|
|
||||||
.span_to_snippet(self_arg.span)
|
|
||||||
.is_ok()
|
|
||||||
{
|
|
||||||
self_arg.span
|
|
||||||
} else {
|
|
||||||
fn_call_span
|
|
||||||
},
|
|
||||||
"calling this operator moves the left-hand side",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CallKind::Normal { self_arg, desugaring, is_option_or_result } => {
|
|
||||||
let self_arg = self_arg.unwrap();
|
|
||||||
if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring {
|
|
||||||
err.span_label(
|
|
||||||
fn_call_span,
|
|
||||||
&format!(
|
|
||||||
"{} {}moved due to this implicit call to `.into_iter()`{}",
|
|
||||||
place_name, partially_str, loop_message
|
|
||||||
),
|
|
||||||
);
|
|
||||||
let sess = self.infcx.tcx.sess;
|
|
||||||
let ty = used_place.ty(self.body, self.infcx.tcx).ty;
|
|
||||||
// If we have a `&mut` ref, we need to reborrow.
|
|
||||||
if let ty::Ref(_, _, hir::Mutability::Mut) = ty.kind() {
|
|
||||||
// If we are in a loop this will be suggested later.
|
|
||||||
if !is_loop_move {
|
|
||||||
err.span_suggestion_verbose(
|
|
||||||
move_span.shrink_to_lo(),
|
|
||||||
&format!(
|
|
||||||
"consider creating a fresh reborrow of {} here",
|
|
||||||
self.describe_place(moved_place.as_ref())
|
|
||||||
.map(|n| format!("`{}`", n))
|
|
||||||
.unwrap_or_else(
|
|
||||||
|| "the mutable reference".to_string()
|
|
||||||
),
|
|
||||||
),
|
|
||||||
"&mut *".to_string(),
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else if let Ok(snippet) =
|
|
||||||
sess.source_map().span_to_snippet(move_span)
|
|
||||||
{
|
|
||||||
err.span_suggestion(
|
|
||||||
move_span,
|
|
||||||
"consider borrowing to avoid moving into the for loop",
|
|
||||||
format!("&{}", snippet),
|
|
||||||
Applicability::MaybeIncorrect,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err.span_label(
|
|
||||||
fn_call_span,
|
|
||||||
&format!(
|
|
||||||
"{} {}moved due to this method call{}",
|
|
||||||
place_name, partially_str, loop_message
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if is_option_or_result && maybe_reinitialized_locations.is_empty() {
|
|
||||||
err.span_suggestion_verbose(
|
|
||||||
fn_call_span.shrink_to_lo(),
|
|
||||||
"consider calling `.as_ref()` to borrow the type's contents",
|
|
||||||
"as_ref().".to_string(),
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// Avoid pointing to the same function in multiple different
|
|
||||||
// error messages.
|
|
||||||
if span != DUMMY_SP && self.fn_self_span_reported.insert(self_arg.span)
|
|
||||||
{
|
|
||||||
err.span_note(
|
|
||||||
self_arg.span,
|
|
||||||
&format!("this function takes ownership of the receiver `self`, which moves {}", place_name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Other desugarings takes &self, which cannot cause a move
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err.span_label(
|
|
||||||
move_span,
|
|
||||||
format!("value {}moved{} here{}", partially_str, move_msg, 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(
|
|
||||||
&mut err,
|
|
||||||
format!(
|
|
||||||
"variable {}moved due to use{}",
|
|
||||||
partially_str,
|
|
||||||
move_spans.describe()
|
|
||||||
),
|
|
||||||
"moved",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let (UseSpans::PatUse(span), []) =
|
if let (UseSpans::PatUse(span), []) =
|
||||||
(move_spans, &maybe_reinitialized_locations[..])
|
(move_spans, &maybe_reinitialized_locations[..])
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
//! Borrow checker diagnostics.
|
//! Borrow checker diagnostics.
|
||||||
|
|
||||||
use rustc_const_eval::util::call_kind;
|
use rustc_const_eval::util::{call_kind, CallDesugaringKind};
|
||||||
use rustc_errors::Diagnostic;
|
use rustc_errors::{Applicability, Diagnostic};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::Namespace;
|
use rustc_hir::def::Namespace;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::GeneratorKind;
|
use rustc_hir::GeneratorKind;
|
||||||
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_middle::mir::{
|
use rustc_middle::mir::{
|
||||||
AggregateKind, Constant, FakeReadCause, Field, Local, LocalInfo, LocalKind, Location, Operand,
|
AggregateKind, Constant, FakeReadCause, Field, Local, LocalInfo, LocalKind, Location, Operand,
|
||||||
Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
|
Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
|
||||||
|
@ -13,8 +14,9 @@ use rustc_middle::mir::{
|
||||||
use rustc_middle::ty::print::Print;
|
use rustc_middle::ty::print::Print;
|
||||||
use rustc_middle::ty::{self, DefIdTree, Instance, Ty, TyCtxt};
|
use rustc_middle::ty::{self, DefIdTree, Instance, Ty, TyCtxt};
|
||||||
use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult};
|
use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult};
|
||||||
use rustc_span::{symbol::sym, Span};
|
use rustc_span::{symbol::sym, Span, DUMMY_SP};
|
||||||
use rustc_target::abi::VariantIdx;
|
use rustc_target::abi::VariantIdx;
|
||||||
|
use rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions;
|
||||||
|
|
||||||
use super::borrow_set::BorrowData;
|
use super::borrow_set::BorrowData;
|
||||||
use super::MirBorrowckCtxt;
|
use super::MirBorrowckCtxt;
|
||||||
|
@ -482,9 +484,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
BorrowedContentSource::DerefSharedRef
|
BorrowedContentSource::DerefSharedRef
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|
||||||
/// Return the name of the provided `Ty` (that must be a reference) with a synthesized lifetime
|
/// Return the name of the provided `Ty` (that must be a reference) with a synthesized lifetime
|
||||||
/// name where required.
|
/// name where required.
|
||||||
pub(super) fn get_name_for_ty(&self, ty: Ty<'tcx>, counter: usize) -> String {
|
pub(super) fn get_name_for_ty(&self, ty: Ty<'tcx>, counter: usize) -> String {
|
||||||
|
@ -995,4 +995,173 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
let span = self.body.source_info(borrow.reserve_location).span;
|
let span = self.body.source_info(borrow.reserve_location).span;
|
||||||
self.borrow_spans(span, borrow.reserve_location)
|
self.borrow_spans(span, borrow.reserve_location)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn explain_captures(
|
||||||
|
&mut self,
|
||||||
|
err: &mut Diagnostic,
|
||||||
|
span: Span,
|
||||||
|
move_span: Span,
|
||||||
|
move_spans: UseSpans<'tcx>,
|
||||||
|
moved_place: Place<'tcx>,
|
||||||
|
used_place: Option<PlaceRef<'tcx>>,
|
||||||
|
partially_str: &str,
|
||||||
|
loop_message: &str,
|
||||||
|
move_msg: &str,
|
||||||
|
is_loop_move: bool,
|
||||||
|
maybe_reinitialized_locations_is_empty: bool,
|
||||||
|
) {
|
||||||
|
if let UseSpans::FnSelfUse { var_span, fn_call_span, fn_span, kind } = move_spans {
|
||||||
|
let place_name = self
|
||||||
|
.describe_place(moved_place.as_ref())
|
||||||
|
.map(|n| format!("`{}`", n))
|
||||||
|
.unwrap_or_else(|| "value".to_owned());
|
||||||
|
match kind {
|
||||||
|
CallKind::FnCall { fn_trait_id, .. }
|
||||||
|
if Some(fn_trait_id) == self.infcx.tcx.lang_items().fn_once_trait() =>
|
||||||
|
{
|
||||||
|
err.span_label(
|
||||||
|
fn_call_span,
|
||||||
|
&format!(
|
||||||
|
"{} {}moved due to this call{}",
|
||||||
|
place_name, partially_str, loop_message
|
||||||
|
),
|
||||||
|
);
|
||||||
|
err.span_note(
|
||||||
|
var_span,
|
||||||
|
"this value implements `FnOnce`, which causes it to be moved when called",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
CallKind::Operator { self_arg, .. } => {
|
||||||
|
let self_arg = self_arg.unwrap();
|
||||||
|
err.span_label(
|
||||||
|
fn_call_span,
|
||||||
|
&format!(
|
||||||
|
"{} {}moved due to usage in operator{}",
|
||||||
|
place_name, partially_str, loop_message
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if self.fn_self_span_reported.insert(fn_span) {
|
||||||
|
err.span_note(
|
||||||
|
// Check whether the source is accessible
|
||||||
|
if self
|
||||||
|
.infcx
|
||||||
|
.tcx
|
||||||
|
.sess
|
||||||
|
.source_map()
|
||||||
|
.span_to_snippet(self_arg.span)
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
self_arg.span
|
||||||
|
} else {
|
||||||
|
fn_call_span
|
||||||
|
},
|
||||||
|
"calling this operator moves the left-hand side",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CallKind::Normal { self_arg, desugaring, is_option_or_result } => {
|
||||||
|
let self_arg = self_arg.unwrap();
|
||||||
|
if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring {
|
||||||
|
let ty = moved_place.ty(self.body, self.infcx.tcx).ty;
|
||||||
|
let suggest = match self.infcx.tcx.get_diagnostic_item(sym::IntoIterator) {
|
||||||
|
Some(def_id) => self.infcx.tcx.infer_ctxt().enter(|infcx| {
|
||||||
|
type_known_to_meet_bound_modulo_regions(
|
||||||
|
&infcx,
|
||||||
|
self.param_env,
|
||||||
|
infcx.tcx.mk_imm_ref(
|
||||||
|
infcx.tcx.lifetimes.re_erased,
|
||||||
|
infcx.tcx.erase_regions(ty),
|
||||||
|
),
|
||||||
|
def_id,
|
||||||
|
DUMMY_SP,
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
if suggest {
|
||||||
|
err.span_suggestion_verbose(
|
||||||
|
move_span.shrink_to_lo(),
|
||||||
|
&format!(
|
||||||
|
"consider iterating over a slice of the `{}`'s content to \
|
||||||
|
avoid moving into the `for` loop",
|
||||||
|
ty,
|
||||||
|
),
|
||||||
|
"&".to_string(),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
err.span_label(
|
||||||
|
fn_call_span,
|
||||||
|
&format!(
|
||||||
|
"{} {}moved due to this implicit call to `.into_iter()`{}",
|
||||||
|
place_name, partially_str, loop_message
|
||||||
|
),
|
||||||
|
);
|
||||||
|
// If we have a `&mut` ref, we need to reborrow.
|
||||||
|
if let Some(ty::Ref(_, _, hir::Mutability::Mut)) = used_place
|
||||||
|
.map(|used_place| used_place.ty(self.body, self.infcx.tcx).ty.kind())
|
||||||
|
{
|
||||||
|
// If we are in a loop this will be suggested later.
|
||||||
|
if !is_loop_move {
|
||||||
|
err.span_suggestion_verbose(
|
||||||
|
move_span.shrink_to_lo(),
|
||||||
|
&format!(
|
||||||
|
"consider creating a fresh reborrow of {} here",
|
||||||
|
self.describe_place(moved_place.as_ref())
|
||||||
|
.map(|n| format!("`{}`", n))
|
||||||
|
.unwrap_or_else(|| "the mutable reference".to_string()),
|
||||||
|
),
|
||||||
|
"&mut *".to_string(),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err.span_label(
|
||||||
|
fn_call_span,
|
||||||
|
&format!(
|
||||||
|
"{} {}moved due to this method call{}",
|
||||||
|
place_name, partially_str, loop_message
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if is_option_or_result && maybe_reinitialized_locations_is_empty {
|
||||||
|
err.span_suggestion_verbose(
|
||||||
|
fn_call_span.shrink_to_lo(),
|
||||||
|
"consider calling `.as_ref()` to borrow the type's contents",
|
||||||
|
"as_ref().".to_string(),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Avoid pointing to the same function in multiple different
|
||||||
|
// error messages.
|
||||||
|
if span != DUMMY_SP && self.fn_self_span_reported.insert(self_arg.span) {
|
||||||
|
err.span_note(
|
||||||
|
self_arg.span,
|
||||||
|
&format!("this function takes ownership of the receiver `self`, which moves {}", place_name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Other desugarings takes &self, which cannot cause a move
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if move_span != span || !loop_message.is_empty() {
|
||||||
|
err.span_label(
|
||||||
|
move_span,
|
||||||
|
format!("value {}moved{} here{}", partially_str, move_msg, 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 {}moved due to use{}", partially_str, move_spans.describe()),
|
||||||
|
"moved",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
use rustc_const_eval::util::CallDesugaringKind;
|
|
||||||
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
|
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_mir_dataflow::move_paths::{
|
use rustc_mir_dataflow::move_paths::{
|
||||||
IllegalMoveOrigin, IllegalMoveOriginKind, LookupResult, MoveError, MovePathIndex,
|
IllegalMoveOrigin, IllegalMoveOriginKind, LookupResult, MoveError, MovePathIndex,
|
||||||
};
|
};
|
||||||
use rustc_span::{sym, Span, DUMMY_SP};
|
use rustc_span::{sym, Span};
|
||||||
use rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions;
|
|
||||||
|
|
||||||
use crate::diagnostics::{CallKind, UseSpans};
|
use crate::diagnostics::UseSpans;
|
||||||
use crate::prefixes::PrefixSet;
|
use crate::prefixes::PrefixSet;
|
||||||
use crate::MirBorrowckCtxt;
|
use crate::MirBorrowckCtxt;
|
||||||
|
|
||||||
|
@ -409,34 +406,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
".as_ref()".to_string(),
|
".as_ref()".to_string(),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
} else if let Some(UseSpans::FnSelfUse {
|
} else if let Some(use_spans) = use_spans {
|
||||||
kind:
|
self.explain_captures(
|
||||||
CallKind::Normal { desugaring: Some((CallDesugaringKind::ForLoopIntoIter, _)), .. },
|
&mut err, span, span, use_spans, move_place, None, "", "", "", false, true,
|
||||||
..
|
);
|
||||||
}) = use_spans
|
|
||||||
{
|
|
||||||
let suggest = match self.infcx.tcx.get_diagnostic_item(sym::IntoIterator) {
|
|
||||||
Some(def_id) => self.infcx.tcx.infer_ctxt().enter(|infcx| {
|
|
||||||
type_known_to_meet_bound_modulo_regions(
|
|
||||||
&infcx,
|
|
||||||
self.param_env,
|
|
||||||
infcx
|
|
||||||
.tcx
|
|
||||||
.mk_imm_ref(infcx.tcx.lifetimes.re_erased, infcx.tcx.erase_regions(ty)),
|
|
||||||
def_id,
|
|
||||||
DUMMY_SP,
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
_ => false,
|
|
||||||
};
|
|
||||||
if suggest {
|
|
||||||
err.span_suggestion_verbose(
|
|
||||||
span.shrink_to_lo(),
|
|
||||||
&format!("consider iterating over a slice of the `{}`'s content", ty),
|
|
||||||
"&".to_string(),
|
|
||||||
Applicability::MaybeIncorrect,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
|
@ -491,11 +464,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
self.note_type_does_not_implement_copy(err, &place_desc, place_ty, Some(span), "");
|
self.note_type_does_not_implement_copy(err, &place_desc, place_ty, Some(span), "");
|
||||||
|
|
||||||
use_spans.args_span_label(err, format!("move out of {} occurs here", place_desc));
|
use_spans.args_span_label(err, format!("move out of {} occurs here", place_desc));
|
||||||
use_spans.var_span_label(
|
|
||||||
err,
|
|
||||||
format!("move occurs due to use{}", use_spans.describe()),
|
|
||||||
"moved",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,8 @@ error[E0507]: cannot move out of `foo` in pattern guard
|
||||||
--> $DIR/borrowck-feature-nll-overrides-migrate.rs:22:18
|
--> $DIR/borrowck-feature-nll-overrides-migrate.rs:22:18
|
||||||
|
|
|
|
||||||
LL | (|| { let bar = foo; bar.take() })();
|
LL | (|| { let bar = foo; bar.take() })();
|
||||||
| ^^ ---
|
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
||||||
| | |
|
| |
|
||||||
| | move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
|
||||||
| | move occurs due to use in closure
|
|
||||||
| move out of `foo` occurs here
|
| move out of `foo` occurs here
|
||||||
|
|
|
|
||||||
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
||||||
|
|
|
@ -2,10 +2,8 @@ error[E0507]: cannot move out of `foo` in pattern guard
|
||||||
--> $DIR/borrowck-feature-nll-overrides-migrate.rs:22:18
|
--> $DIR/borrowck-feature-nll-overrides-migrate.rs:22:18
|
||||||
|
|
|
|
||||||
LL | (|| { let bar = foo; bar.take() })();
|
LL | (|| { let bar = foo; bar.take() })();
|
||||||
| ^^ ---
|
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
||||||
| | |
|
| |
|
||||||
| | move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
|
||||||
| | move occurs due to use in closure
|
|
||||||
| move out of `foo` occurs here
|
| move out of `foo` occurs here
|
||||||
|
|
|
|
||||||
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
||||||
|
|
|
@ -8,8 +8,8 @@ LL | let _g = to_fn_mut(|| {
|
||||||
LL | | let _h = to_fn_once(move || -> isize { *bar });
|
LL | | let _h = to_fn_once(move || -> isize { *bar });
|
||||||
| | ^^^^^^^^^^^^^^^^ ----
|
| | ^^^^^^^^^^^^^^^^ ----
|
||||||
| | | |
|
| | | |
|
||||||
|
| | | variable moved due to use in closure
|
||||||
| | | move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
|
| | | move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
|
||||||
| | | move occurs due to use in closure
|
|
||||||
| | move out of `bar` occurs here
|
| | move out of `bar` occurs here
|
||||||
LL | | });
|
LL | | });
|
||||||
| |_____- captured by this `FnMut` closure
|
| |_____- captured by this `FnMut` closure
|
||||||
|
|
|
@ -2,7 +2,16 @@ error[E0507]: cannot move out of an `Rc`
|
||||||
--> $DIR/borrowck-move-out-of-overloaded-auto-deref.rs:4:14
|
--> $DIR/borrowck-move-out-of-overloaded-auto-deref.rs:4:14
|
||||||
|
|
|
|
||||||
LL | let _x = Rc::new(vec![1, 2]).into_iter();
|
LL | let _x = Rc::new(vec![1, 2]).into_iter();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `Vec<i32>`, which does not implement the `Copy` trait
|
| ^^^^^^^^^^^^^^^^^^^^-----------
|
||||||
|
| | |
|
||||||
|
| | value moved due to this method call
|
||||||
|
| move occurs because value has type `Vec<i32>`, which does not implement the `Copy` trait
|
||||||
|
|
|
||||||
|
note: this function takes ownership of the receiver `self`, which moves value
|
||||||
|
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | fn into_iter(self) -> Self::IntoIter;
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,8 @@ error[E0507]: cannot move out of `foo` in pattern guard
|
||||||
--> $DIR/issue-27282-mutation-in-guard.rs:6:18
|
--> $DIR/issue-27282-mutation-in-guard.rs:6:18
|
||||||
|
|
|
|
||||||
LL | (|| { let bar = foo; bar.take() })();
|
LL | (|| { let bar = foo; bar.take() })();
|
||||||
| ^^ ---
|
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
||||||
| | |
|
| |
|
||||||
| | move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
|
||||||
| | move occurs due to use in closure
|
|
||||||
| move out of `foo` occurs here
|
| move out of `foo` occurs here
|
||||||
|
|
|
|
||||||
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
||||||
|
|
|
@ -6,10 +6,18 @@ LL | let y = vec![format!("World")];
|
||||||
LL | call(|| {
|
LL | call(|| {
|
||||||
| __________-
|
| __________-
|
||||||
LL | | y.into_iter();
|
LL | | y.into_iter();
|
||||||
| | ^ move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait
|
| | ^ ----------- `y` moved due to this method call
|
||||||
|
| | |
|
||||||
|
| | move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait
|
||||||
LL | |
|
LL | |
|
||||||
LL | | });
|
LL | | });
|
||||||
| |_____- captured by this `Fn` closure
|
| |_____- captured by this `Fn` closure
|
||||||
|
|
|
||||||
|
note: this function takes ownership of the receiver `self`, which moves `y`
|
||||||
|
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | fn into_iter(self) -> Self::IntoIter;
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,16 @@ error[E0507]: cannot move out of dereference of `Ref<'_, TheDarkKnight>`
|
||||||
--> $DIR/E0507.rs:12:5
|
--> $DIR/E0507.rs:12:5
|
||||||
|
|
|
|
||||||
LL | x.borrow().nothing_is_true();
|
LL | x.borrow().nothing_is_true();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `TheDarkKnight`, which does not implement the `Copy` trait
|
| ^^^^^^^^^^^-----------------
|
||||||
|
| | |
|
||||||
|
| | value moved due to this method call
|
||||||
|
| move occurs because value has type `TheDarkKnight`, which does not implement the `Copy` trait
|
||||||
|
|
|
||||||
|
note: this function takes ownership of the receiver `self`, which moves value
|
||||||
|
--> $DIR/E0507.rs:6:24
|
||||||
|
|
|
||||||
|
LL | fn nothing_is_true(self) {}
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,8 @@ error[E0507]: cannot move out of `foo` in pattern guard
|
||||||
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:9:19
|
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:9:19
|
||||||
|
|
|
|
||||||
LL | if { (|| { let bar = foo; bar.take() })(); false } => {},
|
LL | if { (|| { let bar = foo; bar.take() })(); false } => {},
|
||||||
| ^^ ---
|
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
||||||
| | |
|
| |
|
||||||
| | move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
|
||||||
| | move occurs due to use in closure
|
|
||||||
| move out of `foo` occurs here
|
| move out of `foo` occurs here
|
||||||
|
|
|
|
||||||
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
||||||
|
|
|
@ -4,10 +4,7 @@ error[E0382]: borrow of moved value: `bad_letters`
|
||||||
LL | let mut bad_letters = vec!['e', 't', 'o', 'i'];
|
LL | let mut bad_letters = vec!['e', 't', 'o', 'i'];
|
||||||
| --------------- move occurs because `bad_letters` has type `Vec<char>`, which does not implement the `Copy` trait
|
| --------------- move occurs because `bad_letters` has type `Vec<char>`, which does not implement the `Copy` trait
|
||||||
LL | for l in bad_letters {
|
LL | for l in bad_letters {
|
||||||
| -----------
|
| ----------- `bad_letters` moved due to this implicit call to `.into_iter()`
|
||||||
| |
|
|
||||||
| `bad_letters` moved due to this implicit call to `.into_iter()`
|
|
||||||
| help: consider borrowing to avoid moving into the for loop: `&bad_letters`
|
|
||||||
...
|
...
|
||||||
LL | bad_letters.push('s');
|
LL | bad_letters.push('s');
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ value borrowed here after move
|
| ^^^^^^^^^^^^^^^^^^^^^ value borrowed here after move
|
||||||
|
@ -17,6 +14,10 @@ note: this function takes ownership of the receiver `self`, which moves `bad_let
|
||||||
|
|
|
|
||||||
LL | fn into_iter(self) -> Self::IntoIter;
|
LL | fn into_iter(self) -> Self::IntoIter;
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
help: consider iterating over a slice of the `Vec<char>`'s content to avoid moving into the `for` loop
|
||||||
|
|
|
||||||
|
LL | for l in &bad_letters {
|
||||||
|
| +
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,7 @@ error[E0382]: use of moved value: `orig`
|
||||||
LL | let orig = vec![true];
|
LL | let orig = vec![true];
|
||||||
| ---- move occurs because `orig` has type `Vec<bool>`, which does not implement the `Copy` trait
|
| ---- move occurs because `orig` has type `Vec<bool>`, which does not implement the `Copy` trait
|
||||||
LL | for _val in orig {}
|
LL | for _val in orig {}
|
||||||
| ----
|
| ---- `orig` moved due to this implicit call to `.into_iter()`
|
||||||
| |
|
|
||||||
| `orig` moved due to this implicit call to `.into_iter()`
|
|
||||||
| help: consider borrowing to avoid moving into the for loop: `&orig`
|
|
||||||
LL | let _closure = || orig;
|
LL | let _closure = || orig;
|
||||||
| ^^ ---- use occurs due to use in closure
|
| ^^ ---- use occurs due to use in closure
|
||||||
| |
|
| |
|
||||||
|
@ -18,6 +15,10 @@ note: this function takes ownership of the receiver `self`, which moves `orig`
|
||||||
|
|
|
|
||||||
LL | fn into_iter(self) -> Self::IntoIter;
|
LL | fn into_iter(self) -> Self::IntoIter;
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
help: consider iterating over a slice of the `Vec<bool>`'s content to avoid moving into the `for` loop
|
||||||
|
|
|
||||||
|
LL | for _val in &orig {}
|
||||||
|
| +
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,7 @@ error[E0382]: use of moved value: `x`
|
||||||
LL | fn foo(x: Vec<S>) {
|
LL | fn foo(x: Vec<S>) {
|
||||||
| - move occurs because `x` has type `Vec<S>`, which does not implement the `Copy` trait
|
| - move occurs because `x` has type `Vec<S>`, which does not implement the `Copy` trait
|
||||||
LL | for y in x {
|
LL | for y in x {
|
||||||
| -
|
| - `x` moved due to this implicit call to `.into_iter()`
|
||||||
| |
|
|
||||||
| `x` moved due to this implicit call to `.into_iter()`
|
|
||||||
| help: consider borrowing to avoid moving into the for loop: `&x`
|
|
||||||
...
|
...
|
||||||
LL | let z = x;
|
LL | let z = x;
|
||||||
| ^ value used here after move
|
| ^ value used here after move
|
||||||
|
@ -17,6 +14,10 @@ note: this function takes ownership of the receiver `self`, which moves `x`
|
||||||
|
|
|
|
||||||
LL | fn into_iter(self) -> Self::IntoIter;
|
LL | fn into_iter(self) -> Self::IntoIter;
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
help: consider iterating over a slice of the `Vec<S>`'s content to avoid moving into the `for` loop
|
||||||
|
|
|
||||||
|
LL | for y in &x {
|
||||||
|
| +
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,7 @@ error[E0382]: use of moved value: `b`
|
||||||
LL | let b = Box::new(true);
|
LL | let b = Box::new(true);
|
||||||
| - move occurs because `b` has type `Box<bool>`, which does not implement the `Copy` trait
|
| - move occurs because `b` has type `Box<bool>`, which does not implement the `Copy` trait
|
||||||
LL | test!({b});
|
LL | test!({b});
|
||||||
| ^
|
| ^ value used here after move
|
||||||
| |
|
|
||||||
| value moved here
|
|
||||||
| value used here after move
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -119,12 +119,14 @@ error[E0382]: use of moved value: `implicit_into_iter`
|
||||||
LL | let implicit_into_iter = vec![true];
|
LL | let implicit_into_iter = vec![true];
|
||||||
| ------------------ move occurs because `implicit_into_iter` has type `Vec<bool>`, which does not implement the `Copy` trait
|
| ------------------ move occurs because `implicit_into_iter` has type `Vec<bool>`, which does not implement the `Copy` trait
|
||||||
LL | for _val in implicit_into_iter {}
|
LL | for _val in implicit_into_iter {}
|
||||||
| ------------------
|
| ------------------ `implicit_into_iter` moved due to this implicit call to `.into_iter()`
|
||||||
| |
|
|
||||||
| `implicit_into_iter` moved due to this implicit call to `.into_iter()`
|
|
||||||
| help: consider borrowing to avoid moving into the for loop: `&implicit_into_iter`
|
|
||||||
LL | implicit_into_iter;
|
LL | implicit_into_iter;
|
||||||
| ^^^^^^^^^^^^^^^^^^ value used here after move
|
| ^^^^^^^^^^^^^^^^^^ value used here after move
|
||||||
|
|
|
||||||
|
help: consider iterating over a slice of the `Vec<bool>`'s content to avoid moving into the `for` loop
|
||||||
|
|
|
||||||
|
LL | for _val in &implicit_into_iter {}
|
||||||
|
| +
|
||||||
|
|
||||||
error[E0382]: use of moved value: `explicit_into_iter`
|
error[E0382]: use of moved value: `explicit_into_iter`
|
||||||
--> $DIR/move-fn-self-receiver.rs:67:5
|
--> $DIR/move-fn-self-receiver.rs:67:5
|
||||||
|
|
|
@ -5,10 +5,7 @@ LL | let x: Box<_> = Box::new(1);
|
||||||
| - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
|
| - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
|
||||||
...
|
...
|
||||||
LL | (_, 2) if take(x) => (),
|
LL | (_, 2) if take(x) => (),
|
||||||
| ^
|
| ^ value used here after move
|
||||||
| |
|
|
||||||
| value moved here
|
|
||||||
| value used here after move
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,8 @@ error[E0507]: cannot move out of `foo` in pattern guard
|
||||||
--> $DIR/match-guards-always-borrow.rs:8:14
|
--> $DIR/match-guards-always-borrow.rs:8:14
|
||||||
|
|
|
|
||||||
LL | (|| { let bar = foo; bar.take() })();
|
LL | (|| { let bar = foo; bar.take() })();
|
||||||
| ^^ ---
|
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
||||||
| | |
|
| |
|
||||||
| | move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
|
||||||
| | move occurs due to use in closure
|
|
||||||
| move out of `foo` occurs here
|
| move out of `foo` occurs here
|
||||||
|
|
|
|
||||||
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
|
||||||
|
|
|
@ -13,16 +13,17 @@ LL | let a = vec![1, 2, 3];
|
||||||
| - move occurs because `a` has type `Vec<i32>`, which does not implement the `Copy` trait
|
| - move occurs because `a` has type `Vec<i32>`, which does not implement the `Copy` trait
|
||||||
LL | for i in &a {
|
LL | for i in &a {
|
||||||
LL | for j in a {
|
LL | for j in a {
|
||||||
| ^
|
| ^ `a` moved due to this implicit call to `.into_iter()`, in previous iteration of loop
|
||||||
| |
|
|
||||||
| `a` moved due to this implicit call to `.into_iter()`, in previous iteration of loop
|
|
||||||
| help: consider borrowing to avoid moving into the for loop: `&a`
|
|
||||||
|
|
|
|
||||||
note: this function takes ownership of the receiver `self`, which moves `a`
|
note: this function takes ownership of the receiver `self`, which moves `a`
|
||||||
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
|
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
|
||||||
|
|
|
|
||||||
LL | fn into_iter(self) -> Self::IntoIter;
|
LL | fn into_iter(self) -> Self::IntoIter;
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
help: consider iterating over a slice of the `Vec<i32>`'s content to avoid moving into the `for` loop
|
||||||
|
|
|
||||||
|
LL | for j in &a {
|
||||||
|
| +
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,17 @@ error[E0507]: cannot move out of `self.v` which is behind a shared reference
|
||||||
--> $DIR/for-i-in-vec.rs:11:18
|
--> $DIR/for-i-in-vec.rs:11:18
|
||||||
|
|
|
|
||||||
LL | for _ in self.v {
|
LL | for _ in self.v {
|
||||||
| ^^^^^^ move occurs because `self.v` has type `Vec<u32>`, which does not implement the `Copy` trait
|
| ^^^^^^
|
||||||
|
| |
|
||||||
|
| `self.v` moved due to this implicit call to `.into_iter()`
|
||||||
|
| move occurs because `self.v` has type `Vec<u32>`, which does not implement the `Copy` trait
|
||||||
|
|
|
|
||||||
help: consider iterating over a slice of the `Vec<u32>`'s content
|
note: this function takes ownership of the receiver `self`, which moves `self.v`
|
||||||
|
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | fn into_iter(self) -> Self::IntoIter;
|
||||||
|
| ^^^^
|
||||||
|
help: consider iterating over a slice of the `Vec<u32>`'s content to avoid moving into the `for` loop
|
||||||
|
|
|
|
||||||
LL | for _ in &self.v {
|
LL | for _ in &self.v {
|
||||||
| +
|
| +
|
||||||
|
@ -13,9 +21,12 @@ error[E0507]: cannot move out of `self.h` which is behind a shared reference
|
||||||
--> $DIR/for-i-in-vec.rs:13:18
|
--> $DIR/for-i-in-vec.rs:13:18
|
||||||
|
|
|
|
||||||
LL | for _ in self.h {
|
LL | for _ in self.h {
|
||||||
| ^^^^^^ move occurs because `self.h` has type `HashMap<i32, i32>`, which does not implement the `Copy` trait
|
| ^^^^^^
|
||||||
|
| |
|
||||||
|
| `self.h` moved due to this implicit call to `.into_iter()`
|
||||||
|
| move occurs because `self.h` has type `HashMap<i32, i32>`, which does not implement the `Copy` trait
|
||||||
|
|
|
|
||||||
help: consider iterating over a slice of the `HashMap<i32, i32>`'s content
|
help: consider iterating over a slice of the `HashMap<i32, i32>`'s content to avoid moving into the `for` loop
|
||||||
|
|
|
|
||||||
LL | for _ in &self.h {
|
LL | for _ in &self.h {
|
||||||
| +
|
| +
|
||||||
|
@ -24,9 +35,17 @@ error[E0507]: cannot move out of a shared reference
|
||||||
--> $DIR/for-i-in-vec.rs:21:19
|
--> $DIR/for-i-in-vec.rs:21:19
|
||||||
|
|
|
|
||||||
LL | for loader in *LOADERS {
|
LL | for loader in *LOADERS {
|
||||||
| ^^^^^^^^ move occurs because value has type `Vec<&u8>`, which does not implement the `Copy` trait
|
| ^^^^^^^^
|
||||||
|
| |
|
||||||
|
| value moved due to this implicit call to `.into_iter()`
|
||||||
|
| move occurs because value has type `Vec<&u8>`, which does not implement the `Copy` trait
|
||||||
|
|
|
|
||||||
help: consider iterating over a slice of the `Vec<&u8>`'s content
|
note: this function takes ownership of the receiver `self`, which moves value
|
||||||
|
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | fn into_iter(self) -> Self::IntoIter;
|
||||||
|
| ^^^^
|
||||||
|
help: consider iterating over a slice of the `Vec<&u8>`'s content to avoid moving into the `for` loop
|
||||||
|
|
|
|
||||||
LL | for loader in &*LOADERS {
|
LL | for loader in &*LOADERS {
|
||||||
| +
|
| +
|
||||||
|
|
|
@ -12,8 +12,8 @@ LL | |
|
||||||
LL | | var = Some(NotCopyable);
|
LL | | var = Some(NotCopyable);
|
||||||
| | ---
|
| | ---
|
||||||
| | |
|
| | |
|
||||||
|
| | variable moved due to use in closure
|
||||||
| | move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
|
| | move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
|
||||||
| | move occurs due to use in closure
|
|
||||||
LL | | }
|
LL | | }
|
||||||
LL | | });
|
LL | | });
|
||||||
| |_____- captured by this `FnMut` closure
|
| |_____- captured by this `FnMut` closure
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue