]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #94515 - estebank:tweak-move-error, r=davidtwco
authorbors <bors@rust-lang.org>
Wed, 9 Mar 2022 08:58:47 +0000 (08:58 +0000)
committerbors <bors@rust-lang.org>
Wed, 9 Mar 2022 08:58:47 +0000 (08:58 +0000)
Tweak move error

Point at method definition that causes type to be consumed.

Fix #94056.

21 files changed:
compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
compiler/rustc_borrowck/src/diagnostics/mod.rs
compiler/rustc_borrowck/src/diagnostics/move_errors.rs
src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.edition.stderr
src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.zflag.stderr
src/test/ui/borrowck/borrowck-move-by-capture.stderr
src/test/ui/borrowck/borrowck-move-out-of-overloaded-auto-deref.stderr
src/test/ui/borrowck/issue-27282-mutation-in-guard.stderr
src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
src/test/ui/error-codes/E0507.stderr
src/test/ui/issues/issue-27282-move-ref-mut-into-guard.stderr
src/test/ui/issues/issue-61108.stderr
src/test/ui/issues/issue-64559.stderr
src/test/ui/loops/issue-82916.stderr
src/test/ui/moves/issue-46099-move-in-macro.stderr
src/test/ui/moves/move-fn-self-receiver.stderr
src/test/ui/moves/move-in-guard-2.stderr
src/test/ui/nll/match-guards-always-borrow.stderr
src/test/ui/suggestions/borrow-for-loop-head.stderr
src/test/ui/suggestions/for-i-in-vec.stderr
src/test/ui/suggestions/option-content-move2.stderr

index 2a74e1ce8b1b16ef5f1c3154da41ce475048362d..1cbca58ca2590f3ed28ae1d1088efb0984533f4c 100644 (file)
@@ -1,5 +1,5 @@
 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;
@@ -17,7 +17,7 @@
 };
 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 _;
 
@@ -195,144 +195,19 @@ pub(crate) fn report_use_of_moved_or_uninitialized(
                     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[..])
index 754856043b3b52a2ead6b50751526dca021b464f..164ebfed0f7959306de31dc8a6f2373d4502701f 100644 (file)
@@ -1,11 +1,12 @@
 //! 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,
@@ -13,8 +14,9 @@
 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;
@@ -482,9 +484,7 @@ pub(super) fn borrowed_content_source(
             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 {
@@ -995,4 +995,173 @@ pub(super) fn retrieve_borrow_spans(&self, borrow: &BorrowData<'_>) -> UseSpans<
         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",
+                );
+            }
+        }
+    }
 }
index 19091569b4d27de36eea5664281fc9ad8cb76bbf..f76ec031aa9e258e6dc5b8ae35a826d050596d1a 100644 (file)
@@ -1,15 +1,12 @@
-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;
 
@@ -409,34 +406,10 @@ fn report_cannot_move_from_borrowed_content(
                 ".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
     }
@@ -491,11 +464,6 @@ fn add_move_hints(&self, error: GroupedMoveError<'tcx>, err: &mut Diagnostic, sp
                 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",
-                );
             }
         }
     }
index e2c8073241487c805e027e3925b5749ada3d8a23..d88185af778f16b75b31488f5b45bf67488b4ee8 100644 (file)
@@ -2,10 +2,8 @@ error[E0507]: cannot move out of `foo` in 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
index e2c8073241487c805e027e3925b5749ada3d8a23..d88185af778f16b75b31488f5b45bf67488b4ee8 100644 (file)
@@ -2,10 +2,8 @@ error[E0507]: cannot move out of `foo` in 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
index 257ec3fbb7fa237266afbbf31f219c92eea359e4..f81b34a641bf081c1121ea189dcdd929e2a2b626 100644 (file)
@@ -8,8 +8,8 @@ LL |       let _g = to_fn_mut(|| {
 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
index 79745065070977f884d6f4f778251d40acdfea66..800f30b34e58921dd71977b9d9c753562928429a 100644 (file)
@@ -2,7 +2,16 @@ error[E0507]: cannot move out of an `Rc`
   --> $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
 
index 540f7f8a484776d3b36fcb795999f10f3dd074b4..c4ce7e62fda82bc24bb45d8b3f90b7afb8f9664b 100644 (file)
@@ -2,10 +2,8 @@ error[E0507]: cannot move out of `foo` in pattern guard
   --> $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
index 1663ce81d6cf446b5819502eb7b14b8f8c108884..3ea7226200362c77be54afd1e5b56fd1f584691b 100644 (file)
@@ -6,10 +6,18 @@ LL |       let y = vec![format!("World")];
 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
 
index 3837e206169d4756ccfad11ece429cd4f24d937c..ce8d1ef03493c277c960ec783ee3da0f1e1d2697 100644 (file)
@@ -2,7 +2,16 @@ error[E0507]: cannot move out of dereference of `Ref<'_, TheDarkKnight>`
   --> $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
 
index 7895cefb4cb2ed9eb4396f173f4b56f2646ef1b8..a0d32616f83b74f2dad691636171476b1d40cc59 100644 (file)
@@ -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
    |
 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
index 6f345f56d1aa112ff8f8ca44bf0cbcf56d63229e..e5b671d7b7ab0b71bbf6e871864094dd35c6ed2a 100644 (file)
@@ -4,10 +4,7 @@ error[E0382]: borrow of moved value: `bad_letters`
 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
@@ -17,6 +14,10 @@ note: this function takes ownership of the receiver `self`, which moves `bad_let
    |
 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
 
index e0da3fd5195cb26df853777f30ee45abfcc9dd61..ef178bbd155388f94e8b832d5c48c2a6bb65ade4 100644 (file)
@@ -4,10 +4,7 @@ error[E0382]: use of moved value: `orig`
 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
    |                    |
@@ -18,6 +15,10 @@ note: this function takes ownership of the receiver `self`, which moves `orig`
    |
 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
 
index ad42cce71f6865a31262142deb1ef984763cb8a3..57d76016c4539d3e8ff8f0623af847d73ae30a08 100644 (file)
@@ -4,10 +4,7 @@ error[E0382]: use of moved value: `x`
 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
@@ -17,6 +14,10 @@ note: this function takes ownership of the receiver `self`, which moves `x`
    |
 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
 
index db4c3979e3ad694a90ec6c31b2ec5f79b986b5ce..baa87e3e9fdb2111f386b81cfa0ba958d7bb4d80 100644 (file)
@@ -4,10 +4,7 @@ error[E0382]: use of moved value: `b`
 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
 
index 57be5fb4d8a59160181fa33d80b780215bc14049..3a686121a9283c802073af9bd935eab1e72c76db 100644 (file)
@@ -119,12 +119,14 @@ error[E0382]: use of moved value: `implicit_into_iter`
 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
index ea350926b1519f77a1264274880d4dda57509274..8d636c11b78c7bd25500a5dfa364b9c6a4aaea2b 100644 (file)
@@ -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
 ...
 LL |         (_, 2) if take(x) => (),
-   |                        ^
-   |                        |
-   |                        value moved here
-   |                        value used here after move
+   |                        ^ value used here after move
 
 error: aborting due to previous error
 
index df6d65056acd2c8870b6731b7f6c05b8d26abcf4..c0fb5f65382dce4eccdd3be95cecabd71085d28b 100644 (file)
@@ -2,10 +2,8 @@ error[E0507]: cannot move out of `foo` in pattern guard
   --> $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
index 28c319b659765ccbf1bef51cde2b85e12017a248..1059e3d1525aa779fc659c3ad4dbb991fe0f376e 100644 (file)
@@ -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
 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
 
index c39363f762bdd8ee26aab0d62fd8e5e94f905446..88be9e30a764125261b822c14a6e7c761d4d26a2 100644 (file)
@@ -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
    |
 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 {
    |                  +
@@ -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
    |
 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 {
    |                  +
@@ -24,9 +35,17 @@ error[E0507]: cannot move out of a shared reference
   --> $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 {
    |                   +
index a0ce7d05b4d48efecc2aa29787f701d344254ba9..16cbbaba512a4e0c0fe58b505ebc1f872f5bb2bb 100644 (file)
@@ -12,8 +12,8 @@ LL | |
 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