use either::Either;
-use rustc_const_eval::util::{CallDesugaringKind, CallKind};
+use rustc_const_eval::util::CallKind;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir as hir;
};
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
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::traits::TraitEngineExt as _;
is_loop_move = true;
}
- 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 {
- 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",
- );
- }
- }
+ self.explain_captures(
+ &mut err,
+ span,
+ move_span,
+ move_spans,
+ *moved_place,
+ Some(used_place),
+ partially_str,
+ loop_message,
+ move_msg,
+ is_loop_move,
+ maybe_reinitialized_locations.is_empty(),
+ );
if let (UseSpans::PatUse(span), []) =
(move_spans, &maybe_reinitialized_locations[..])
//! Borrow checker diagnostics.
-use rustc_const_eval::util::call_kind;
-use rustc_errors::Diagnostic;
+use rustc_const_eval::util::{call_kind, CallDesugaringKind};
+use rustc_errors::{Applicability, Diagnostic};
use rustc_hir as hir;
use rustc_hir::def::Namespace;
use rustc_hir::def_id::DefId;
use rustc_hir::GeneratorKind;
+use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::mir::{
AggregateKind, Constant, FakeReadCause, Field, Local, LocalInfo, LocalKind, Location, Operand,
Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
use rustc_middle::ty::print::Print;
use rustc_middle::ty::{self, DefIdTree, Instance, Ty, TyCtxt};
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_trait_selection::traits::type_known_to_meet_bound_modulo_regions;
use super::borrow_set::BorrowData;
use super::MirBorrowckCtxt;
BorrowedContentSource::DerefSharedRef
}
}
-}
-impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
/// Return the name of the provided `Ty` (that must be a reference) with a synthesized lifetime
/// name where required.
pub(super) fn get_name_for_ty(&self, ty: Ty<'tcx>, counter: usize) -> String {
let span = self.body.source_info(borrow.reserve_location).span;
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",
+ );
+ }
+ }
+ }
}
-use rustc_const_eval::util::CallDesugaringKind;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
-use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::mir::*;
use rustc_middle::ty;
use rustc_mir_dataflow::move_paths::{
IllegalMoveOrigin, IllegalMoveOriginKind, LookupResult, MoveError, MovePathIndex,
};
-use rustc_span::{sym, Span, DUMMY_SP};
-use rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions;
+use rustc_span::{sym, Span};
-use crate::diagnostics::{CallKind, UseSpans};
+use crate::diagnostics::UseSpans;
use crate::prefixes::PrefixSet;
use crate::MirBorrowckCtxt;
".as_ref()".to_string(),
Applicability::MaybeIncorrect,
);
- } else if let Some(UseSpans::FnSelfUse {
- kind:
- CallKind::Normal { desugaring: Some((CallDesugaringKind::ForLoopIntoIter, _)), .. },
- ..
- }) = 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,
- );
- }
+ } else if let Some(use_spans) = use_spans {
+ self.explain_captures(
+ &mut err, span, span, use_spans, move_place, None, "", "", "", false, true,
+ );
}
err
}
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.var_span_label(
- err,
- format!("move occurs due to use{}", use_spans.describe()),
- "moved",
- );
}
}
}
--> $DIR/borrowck-feature-nll-overrides-migrate.rs:22:18
|
LL | (|| { let bar = foo; bar.take() })();
- | ^^ ---
- | | |
- | | move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
- | | move occurs due to use in closure
+ | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
+ | |
| move out of `foo` occurs here
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
--> $DIR/borrowck-feature-nll-overrides-migrate.rs:22:18
|
LL | (|| { let bar = foo; bar.take() })();
- | ^^ ---
- | | |
- | | move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
- | | move occurs due to use in closure
+ | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
+ | |
| move out of `foo` occurs here
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
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 due to use in closure
| | move out of `bar` occurs here
LL | | });
| |_____- captured by this `FnMut` closure
--> $DIR/borrowck-move-out-of-overloaded-auto-deref.rs:4:14
|
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
--> $DIR/issue-27282-mutation-in-guard.rs:6:18
|
LL | (|| { let bar = foo; bar.take() })();
- | ^^ ---
- | | |
- | | move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
- | | move occurs due to use in closure
+ | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
+ | |
| move out of `foo` occurs here
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
LL | call(|| {
| __________-
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 | | });
| |_____- 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
--> $DIR/E0507.rs:12:5
|
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
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:9:19
|
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 due to use in closure
+ | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
+ | |
| move out of `foo` occurs here
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
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
LL | for l in bad_letters {
- | -----------
- | |
- | `bad_letters` moved due to this implicit call to `.into_iter()`
- | help: consider borrowing to avoid moving into the for loop: `&bad_letters`
+ | ----------- `bad_letters` moved due to this implicit call to `.into_iter()`
...
LL | bad_letters.push('s');
| ^^^^^^^^^^^^^^^^^^^^^ value borrowed here after move
|
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
LL | let orig = vec![true];
| ---- move occurs because `orig` has type `Vec<bool>`, which does not implement the `Copy` trait
LL | for _val in orig {}
- | ----
- | |
- | `orig` moved due to this implicit call to `.into_iter()`
- | help: consider borrowing to avoid moving into the for loop: `&orig`
+ | ---- `orig` moved due to this implicit call to `.into_iter()`
LL | let _closure = || orig;
| ^^ ---- use occurs due to use in closure
| |
|
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
LL | fn foo(x: Vec<S>) {
| - move occurs because `x` has type `Vec<S>`, which does not implement the `Copy` trait
LL | for y in x {
- | -
- | |
- | `x` moved due to this implicit call to `.into_iter()`
- | help: consider borrowing to avoid moving into the for loop: `&x`
+ | - `x` moved due to this implicit call to `.into_iter()`
...
LL | let z = x;
| ^ value used here after move
|
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
LL | let b = Box::new(true);
| - move occurs because `b` has type `Box<bool>`, which does not implement the `Copy` trait
LL | test!({b});
- | ^
- | |
- | value moved here
- | value used here after move
+ | ^ value used here after move
error: aborting due to previous error
LL | let implicit_into_iter = vec![true];
| ------------------ move occurs because `implicit_into_iter` has type `Vec<bool>`, which does not implement the `Copy` trait
LL | for _val in implicit_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`
+ | ------------------ `implicit_into_iter` moved due to this implicit call to `.into_iter()`
LL | implicit_into_iter;
| ^^^^^^^^^^^^^^^^^^ 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`
--> $DIR/move-fn-self-receiver.rs:67:5
| - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
...
LL | (_, 2) if take(x) => (),
- | ^
- | |
- | value moved here
- | value used here after move
+ | ^ value used here after move
error: aborting due to previous error
--> $DIR/match-guards-always-borrow.rs:8:14
|
LL | (|| { let bar = foo; bar.take() })();
- | ^^ ---
- | | |
- | | move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
- | | move occurs due to use in closure
+ | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
+ | |
| move out of `foo` occurs here
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
| - move occurs because `a` has type `Vec<i32>`, which does not implement the `Copy` trait
LL | for i in &a {
LL | for j in a {
- | ^
- | |
- | `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`
+ | ^ `a` moved due to this implicit call to `.into_iter()`, in previous iteration of loop
|
note: this function takes ownership of the receiver `self`, which moves `a`
--> $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<i32>`'s content to avoid moving into the `for` loop
+ |
+LL | for j in &a {
+ | +
error: aborting due to 2 previous errors
--> $DIR/for-i-in-vec.rs:11:18
|
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 {
| +
--> $DIR/for-i-in-vec.rs:13:18
|
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 {
| +
--> $DIR/for-i-in-vec.rs:21:19
|
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
+ |
+note: this function takes ownership of the receiver `self`, which moves value
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
|
-help: consider iterating over a slice of the `Vec<&u8>`'s content
+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 | | 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 due to use in closure
LL | | }
LL | | });
| |_____- captured by this `FnMut` closure