diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index e9c1c1d57b936..3cbbc931d11e4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -18,7 +18,7 @@ use rustc_middle::mir::{ LocalKind, Location, Operand, Place, PlaceRef, PlaceTy, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarDebugInfoContents, find_self_call, }; -use rustc_middle::ty::print::Print; +use rustc_middle::ty::print::{Print, with_no_trimmed_paths}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveOutIndex}; @@ -1374,12 +1374,21 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { &move_spans, ); - let func = tcx.def_path_str(method_did); - err.subdiagnostic(CaptureReasonNote::FuncTakeSelf { - func, - place_name: place_name.clone(), - span: self_arg.span, - }); + let func = with_no_trimmed_paths!(tcx.def_path_str(method_did)); + if let Some((kind, _)) = desugaring { + err.subdiagnostic(CaptureReasonNote::DesugaringFuncTakeSelf { + func, + desugar_name: kind.name(), + place_name: place_name.clone(), + span: self_arg.span, + }); + } else { + err.subdiagnostic(CaptureReasonNote::FuncTakeSelf { + func, + place_name: place_name.clone(), + span: self_arg.span, + }); + } } let parent_did = tcx.parent(method_did); let parent_self_ty = @@ -1400,17 +1409,20 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { var_span: var_span.shrink_to_hi(), }); } - if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring { + if let Some(( + kind @ (CallDesugaringKind::ForLoopIntoIter + | CallDesugaringKind::ForLoopIntoAsyncIter), + _, + )) = desugaring + { let ty = moved_place.ty(self.body, tcx).ty; - let suggest = match tcx.get_diagnostic_item(sym::IntoIterator) { - Some(def_id) => type_known_to_meet_bound_modulo_regions( - self.infcx, - self.infcx.param_env, - Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, ty), - def_id, - ), - _ => false, - }; + let def_id = kind.trait_def_id(tcx); + let suggest = type_known_to_meet_bound_modulo_regions( + self.infcx, + self.infcx.param_env, + Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, ty), + def_id, + ); if suggest { err.subdiagnostic(CaptureReasonSuggest::IterateSlice { ty, @@ -1418,12 +1430,25 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { }); } - err.subdiagnostic(CaptureReasonLabel::ImplicitCall { - fn_call_span, - place_name: &place_name, - is_partial, - is_loop_message, - }); + match kind { + CallDesugaringKind::ForLoopIntoIter => { + err.subdiagnostic(CaptureReasonLabel::ImplicitCall { + fn_call_span, + place_name: &place_name, + is_partial, + is_loop_message, + }); + } + CallDesugaringKind::ForLoopIntoAsyncIter => { + err.subdiagnostic(CaptureReasonLabel::ImplicitAsyncCall { + fn_call_span, + place_name: &place_name, + is_partial, + is_loop_message, + }); + } + _ => {} + } // If the moved place was a `&mut` ref, then we can // suggest to reborrow it where it was moved, so it // will still be valid by the time we get to the usage. @@ -1451,20 +1476,31 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { } } } else { - if let Some((CallDesugaringKind::Await, _)) = desugaring { - err.subdiagnostic(CaptureReasonLabel::Await { - fn_call_span, - place_name: &place_name, - is_partial, - is_loop_message, - }); - } else { - err.subdiagnostic(CaptureReasonLabel::MethodCall { - fn_call_span, - place_name: &place_name, - is_partial, - is_loop_message, - }); + match desugaring { + Some((CallDesugaringKind::Await, _)) => { + err.subdiagnostic(CaptureReasonLabel::Await { + fn_call_span, + place_name: &place_name, + is_partial, + is_loop_message, + }); + } + Some((CallDesugaringKind::QuestionBranch, _)) => { + err.subdiagnostic(CaptureReasonLabel::QuestionMark { + fn_call_span, + place_name: &place_name, + is_partial, + is_loop_message, + }); + } + _ => { + err.subdiagnostic(CaptureReasonLabel::MethodCall { + fn_call_span, + place_name: &place_name, + is_partial, + is_loop_message, + }); + } } // Erase and shadow everything that could be passed to the new infcx. let ty = moved_place.ty(self.body, tcx).ty; diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index cd4d1f16b21af..a0f347679b05a 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -389,6 +389,22 @@ pub(crate) enum CaptureReasonLabel<'a> { is_partial: bool, is_loop_message: bool, }, + #[label( + "{$place_name} {$is_partial -> + [true] partially moved + *[false] moved + } due to the question mark {$is_loop_message -> + [true] operator, in previous iteration of loop + *[false] operator + }" + )] + QuestionMark { + #[primary_span] + fn_call_span: Span, + place_name: &'a str, + is_partial: bool, + is_loop_message: bool, + }, #[label( "{$place_name} {$is_partial -> [true] partially moved @@ -405,6 +421,22 @@ pub(crate) enum CaptureReasonLabel<'a> { is_partial: bool, is_loop_message: bool, }, + #[label( + "{$place_name} {$is_partial -> + [true] partially moved + *[false] moved + } due to this implicit call to {$is_loop_message -> + [true] `.into_async_iter()`, in previous iteration of loop + *[false] `.into_async_iter()` + }" + )] + ImplicitAsyncCall { + #[primary_span] + fn_call_span: Span, + place_name: &'a str, + is_partial: bool, + is_loop_message: bool, + }, #[label( "{$place_name} {$is_partial -> [true] partially moved @@ -498,6 +530,17 @@ pub(crate) enum CaptureReasonNote { #[primary_span] span: Span, }, + #[note( + "the {$desugar_name} is desugared into a call to `{$func}`, which takes ownership of the \ + receiver `self`, which moves {$place_name}" + )] + DesugaringFuncTakeSelf { + desugar_name: &'static str, + func: String, + place_name: String, + #[primary_span] + span: Span, + }, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 15e800666129a..76c0c5f0d3bdf 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -247,7 +247,9 @@ fn build_error_for_const_call<'tcx>( // Don't point at the trait if this is a desugaring... // FIXME(const_trait_impl): we could perhaps do this for `Iterator`. match kind { - CallDesugaringKind::ForLoopIntoIter | CallDesugaringKind::ForLoopNext => { + CallDesugaringKind::ForLoopIntoIter + | CallDesugaringKind::ForLoopIntoAsyncIter + | CallDesugaringKind::ForLoopNext => { error!(NonConstForLoopIntoIter) } CallDesugaringKind::QuestionBranch => { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c874c1af265f8..0acffe45a40b0 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -238,6 +238,7 @@ symbols! { Input, Int, Into, + IntoAsyncIterator, IntoFuture, IntoIterator, IntoIteratorItem, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs index 60ae0cd644460..bdd22f89923f9 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs @@ -17,6 +17,8 @@ use crate::traits::specialization_graph; pub enum CallDesugaringKind { /// for _ in x {} calls x.into_iter() ForLoopIntoIter, + /// for await _ in x {} calls x.into_async_iter() + ForLoopIntoAsyncIter, /// for _ in x {} calls iter.next() ForLoopNext, /// x? calls x.branch() @@ -30,9 +32,22 @@ pub enum CallDesugaringKind { } impl CallDesugaringKind { + pub fn name(&self) -> &'static str { + match self { + CallDesugaringKind::ForLoopIntoIter => "`for` loop", + CallDesugaringKind::ForLoopIntoAsyncIter => "`for await` loop", + CallDesugaringKind::ForLoopNext => "`for` loop", + CallDesugaringKind::QuestionBranch => "question mark operator", + CallDesugaringKind::QuestionFromResidual => "question mark operator", + CallDesugaringKind::TryBlockFromOutput => "try block", + CallDesugaringKind::Await => "`await`", + } + } + pub fn trait_def_id(self, tcx: TyCtxt<'_>) -> DefId { match self { Self::ForLoopIntoIter => tcx.get_diagnostic_item(sym::IntoIterator).unwrap(), + Self::ForLoopIntoAsyncIter => tcx.get_diagnostic_item(sym::IntoAsyncIterator).unwrap(), Self::ForLoopNext => tcx.require_lang_item(LangItem::Iterator, DUMMY_SP), Self::QuestionBranch | Self::TryBlockFromOutput => { tcx.require_lang_item(LangItem::Try, DUMMY_SP) @@ -136,6 +151,10 @@ pub fn call_kind<'tcx>( && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop) { Some((CallDesugaringKind::ForLoopIntoIter, method_args.type_at(0))) + } else if tcx.is_lang_item(method_did, LangItem::IntoAsyncIterIntoIter) + && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop) + { + Some((CallDesugaringKind::ForLoopIntoAsyncIter, method_args.type_at(0))) } else if tcx.is_lang_item(method_did, LangItem::IteratorNext) && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop) { diff --git a/library/core/src/async_iter/async_iter.rs b/library/core/src/async_iter/async_iter.rs index c21c08320bef6..b9e1065e48807 100644 --- a/library/core/src/async_iter/async_iter.rs +++ b/library/core/src/async_iter/async_iter.rs @@ -141,6 +141,7 @@ impl Poll> { /// Converts something into an async iterator #[unstable(feature = "async_iterator", issue = "79024")] +#[rustc_diagnostic_item = "IntoAsyncIterator"] pub trait IntoAsyncIterator { /// The type of the item yielded by the iterator type Item; diff --git a/tests/ui/async-await/async-closures/move-consuming-capture.stderr b/tests/ui/async-await/async-closures/move-consuming-capture.stderr index e28716ca213b3..a6526981c87c1 100644 --- a/tests/ui/async-await/async-closures/move-consuming-capture.stderr +++ b/tests/ui/async-await/async-closures/move-consuming-capture.stderr @@ -9,7 +9,7 @@ LL | x().await; LL | x().await; | ^ value used here after move | -note: `async_call_once` takes ownership of the receiver `self`, which moves `x` +note: `std::ops::AsyncFnOnce::async_call_once` takes ownership of the receiver `self`, which moves `x` --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL help: you could `clone` the value and consume it, if the `NoCopy: Clone` trait bound could be satisfied | diff --git a/tests/ui/async-await/clone-suggestion.stderr b/tests/ui/async-await/clone-suggestion.stderr index 3374068ed3f60..7220fb7dd8f05 100644 --- a/tests/ui/async-await/clone-suggestion.stderr +++ b/tests/ui/async-await/clone-suggestion.stderr @@ -8,7 +8,7 @@ LL | f.await; LL | f.await; | ^ value used here after move | -note: `into_future` takes ownership of the receiver `self`, which moves `f` +note: the `await` is desugared into a call to `std::future::IntoFuture::into_future`, which takes ownership of the receiver `self`, which moves `f` --> $SRC_DIR/core/src/future/into_future.rs:LL:COL help: you can `clone` the value and consume it, but this might not be your desired behavior | diff --git a/tests/ui/async-await/for-await-consumes-iter.stderr b/tests/ui/async-await/for-await-consumes-iter.stderr index a3e5bbcabf5d0..c71ebbcc11c97 100644 --- a/tests/ui/async-await/for-await-consumes-iter.stderr +++ b/tests/ui/async-await/for-await-consumes-iter.stderr @@ -5,17 +5,13 @@ LL | let iter = core::async_iter::from_iter(0..3); | ---- move occurs because `iter` has type `FromIter>`, which does not implement the `Copy` trait LL | let mut count = 0; LL | for await i in iter { - | ---- `iter` moved due to this method call + | ---- `iter` moved due to this implicit call to `.into_async_iter()` ... LL | for await i in iter { | ^^^^ value used here after move | -note: `into_async_iter` takes ownership of the receiver `self`, which moves `iter` +note: the `for await` loop is desugared into a call to `std::async_iter::IntoAsyncIterator::into_async_iter`, which takes ownership of the receiver `self`, which moves `iter` --> $SRC_DIR/core/src/async_iter/async_iter.rs:LL:COL -help: you can `clone` the value and consume it, but this might not be your desired behavior - | -LL | for await i in iter.clone() { - | ++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrow-of-moved-value-in-for-loop-61108.stderr b/tests/ui/borrowck/borrow-of-moved-value-in-for-loop-61108.stderr index 4c3fa5e56dc9b..48a23380d9ba6 100644 --- a/tests/ui/borrowck/borrow-of-moved-value-in-for-loop-61108.stderr +++ b/tests/ui/borrowck/borrow-of-moved-value-in-for-loop-61108.stderr @@ -9,7 +9,7 @@ LL | for l in bad_letters { LL | bad_letters.push('s'); | ^^^^^^^^^^^ value borrowed here after move | -note: `into_iter` takes ownership of the receiver `self`, which moves `bad_letters` +note: the `for` loop is desugared into a call to `std::iter::IntoIterator::into_iter`, which takes ownership of the receiver `self`, which moves `bad_letters` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: consider iterating over a slice of the `Vec`'s content to avoid moving into the `for` loop | diff --git a/tests/ui/borrowck/borrowck-move-out-of-overloaded-auto-deref.stderr b/tests/ui/borrowck/borrowck-move-out-of-overloaded-auto-deref.stderr index 076f0ce3440a0..bec5427a1d428 100644 --- a/tests/ui/borrowck/borrowck-move-out-of-overloaded-auto-deref.stderr +++ b/tests/ui/borrowck/borrowck-move-out-of-overloaded-auto-deref.stderr @@ -6,7 +6,7 @@ LL | let _x = Rc::new(vec![1, 2]).into_iter(); | | | move occurs because value has type `Vec`, which does not implement the `Copy` trait | -note: `into_iter` takes ownership of the receiver `self`, which moves value +note: `std::iter::IntoIterator::into_iter` takes ownership of the receiver `self`, which moves value --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: you can `clone` the value and consume it, but this might not be your desired behavior | diff --git a/tests/ui/borrowck/fn-closure-move-capture-no-reborrow-sugg.stderr b/tests/ui/borrowck/fn-closure-move-capture-no-reborrow-sugg.stderr index e31bae3a4ddf6..f92951313f2a4 100644 --- a/tests/ui/borrowck/fn-closure-move-capture-no-reborrow-sugg.stderr +++ b/tests/ui/borrowck/fn-closure-move-capture-no-reborrow-sugg.stderr @@ -18,7 +18,7 @@ help: `Fn` and `FnMut` closures require captured values to be able to be consume | LL | pub fn in_fn Result<(), ()>>(f: F) -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^ -note: `into_iter` takes ownership of the receiver `self`, which moves `foos` +note: the `for` loop is desugared into a call to `std::iter::IntoIterator::into_iter`, which takes ownership of the receiver `self`, which moves `foos` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL error[E0507]: cannot move out of `foos`, a captured variable in an `FnMut` closure @@ -41,7 +41,7 @@ help: `Fn` and `FnMut` closures require captured values to be able to be consume | LL | pub fn in_fn_mut Result<(), ()>>(mut f: F) -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: `into_iter` takes ownership of the receiver `self`, which moves `foos` +note: the `for` loop is desugared into a call to `std::iter::IntoIterator::into_iter`, which takes ownership of the receiver `self`, which moves `foos` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: consider creating a fresh reborrow of `foos` here | diff --git a/tests/ui/borrowck/issue-83760.stderr b/tests/ui/borrowck/issue-83760.stderr index d120adbc03bb3..a45146a565022 100644 --- a/tests/ui/borrowck/issue-83760.stderr +++ b/tests/ui/borrowck/issue-83760.stderr @@ -27,7 +27,7 @@ LL | foo = Some(Struct); LL | let _y = foo; | ^^^ value used here after move | -note: `Option::::unwrap` takes ownership of the receiver `self`, which moves `foo` +note: `std::option::Option::::unwrap` takes ownership of the receiver `self`, which moves `foo` --> $SRC_DIR/core/src/option.rs:LL:COL help: you could `clone` the value and consume it, if the `Struct: Clone` trait bound could be satisfied | @@ -61,7 +61,7 @@ LL | foo = Some(Struct2); LL | } else if true { LL | foo = Some(Struct2); | ^^^^^^^^^^^^^^^^^^^ -note: `Option::::unwrap` takes ownership of the receiver `self`, which moves `foo` +note: `std::option::Option::::unwrap` takes ownership of the receiver `self`, which moves `foo` --> $SRC_DIR/core/src/option.rs:LL:COL help: you could `clone` the value and consume it, if the `Struct2: Clone` trait bound could be satisfied | diff --git a/tests/ui/borrowck/issue-83924.stderr b/tests/ui/borrowck/issue-83924.stderr index c37de178f2499..8844766397ef7 100644 --- a/tests/ui/borrowck/issue-83924.stderr +++ b/tests/ui/borrowck/issue-83924.stderr @@ -10,7 +10,7 @@ LL | for n in v { LL | for n in v { | ^ value used here after move | -note: `into_iter` takes ownership of the receiver `self`, which moves `v` +note: the `for` loop is desugared into a call to `std::iter::IntoIterator::into_iter`, which takes ownership of the receiver `self`, which moves `v` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: consider creating a fresh reborrow of `v` here | diff --git a/tests/ui/borrowck/moved-into-question-mark.rs b/tests/ui/borrowck/moved-into-question-mark.rs new file mode 100644 index 0000000000000..d09b7b8f6f42d --- /dev/null +++ b/tests/ui/borrowck/moved-into-question-mark.rs @@ -0,0 +1,17 @@ +// https://github.com/rust-lang/rust/issues/89567 +use std::fs; +use std::io; + +fn main() -> io::Result<()> { + for entry in fs::read_dir(".")? { + //~^ NOTE move occurs because `entry` has type `Result + let file_type = entry?.file_type()?; + //~^ NOTE `entry` moved due to the question mark operator + if file_type.is_dir() { + dbg!(entry?.file_name()); //~ ERROR use of moved value + //~^ NOTE value used here after move + //~| NOTE the question mark operator is desugared into a call to `std::ops::Try::branch` + } + } + Ok(()) +} diff --git a/tests/ui/borrowck/moved-into-question-mark.stderr b/tests/ui/borrowck/moved-into-question-mark.stderr new file mode 100644 index 0000000000000..5febf1b73b473 --- /dev/null +++ b/tests/ui/borrowck/moved-into-question-mark.stderr @@ -0,0 +1,22 @@ +error[E0382]: use of moved value: `entry` + --> $DIR/moved-into-question-mark.rs:11:18 + | +LL | for entry in fs::read_dir(".")? { + | ----- move occurs because `entry` has type `Result`, which does not implement the `Copy` trait +LL | +LL | let file_type = entry?.file_type()?; + | ------ `entry` moved due to the question mark operator +... +LL | dbg!(entry?.file_name()); + | ^^^^^ value used here after move + | +note: the question mark operator is desugared into a call to `std::ops::Try::branch`, which takes ownership of the receiver `self`, which moves `entry` + --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL +help: you could `clone` the value and consume it, if the following trait bounds could be satisfied: `DirEntry: Clone` and `std::io::Error: Clone` + | +LL | let file_type = entry.clone()?.file_type()?; + | ++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/borrowck/moved-value-in-closure-suggestion-64559.stderr b/tests/ui/borrowck/moved-value-in-closure-suggestion-64559.stderr index 09d4d04295c7c..557912d0e12dc 100644 --- a/tests/ui/borrowck/moved-value-in-closure-suggestion-64559.stderr +++ b/tests/ui/borrowck/moved-value-in-closure-suggestion-64559.stderr @@ -10,7 +10,7 @@ LL | let _closure = || orig; | | | value used here after move | -note: `into_iter` takes ownership of the receiver `self`, which moves `orig` +note: the `for` loop is desugared into a call to `std::iter::IntoIterator::into_iter`, which takes ownership of the receiver `self`, which moves `orig` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: consider iterating over a slice of the `Vec`'s content to avoid moving into the `for` loop | diff --git a/tests/ui/borrowck/reborrow-sugg-move-then-borrow.stderr b/tests/ui/borrowck/reborrow-sugg-move-then-borrow.stderr index 8590dd9ca3d07..4cbf323a14662 100644 --- a/tests/ui/borrowck/reborrow-sugg-move-then-borrow.stderr +++ b/tests/ui/borrowck/reborrow-sugg-move-then-borrow.stderr @@ -9,7 +9,7 @@ LL | LL | fill_segment(state); | ^^^^^ value borrowed here after move | -note: `into_iter` takes ownership of the receiver `self`, which moves `state` +note: the `for` loop is desugared into a call to `std::iter::IntoIterator::into_iter`, which takes ownership of the receiver `self`, which moves `state` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: consider creating a fresh reborrow of `state` here | diff --git a/tests/ui/borrowck/suggest-as-ref-on-mut-closure.stderr b/tests/ui/borrowck/suggest-as-ref-on-mut-closure.stderr index e2199fa90f263..9435abb7579fe 100644 --- a/tests/ui/borrowck/suggest-as-ref-on-mut-closure.stderr +++ b/tests/ui/borrowck/suggest-as-ref-on-mut-closure.stderr @@ -6,7 +6,7 @@ LL | cb.map(|cb| cb()); | | | move occurs because `*cb` has type `Option<&mut dyn FnMut()>`, which does not implement the `Copy` trait | -note: `Option::::map` takes ownership of the receiver `self`, which moves `*cb` +note: `std::option::Option::::map` takes ownership of the receiver `self`, which moves `*cb` --> $SRC_DIR/core/src/option.rs:LL:COL help: consider calling `.as_ref()` to borrow the value's contents | diff --git a/tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr b/tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr index 08cf528839834..b44ae3b444ec4 100644 --- a/tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr +++ b/tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr @@ -15,7 +15,7 @@ help: `Fn` and `FnMut` closures require captured values to be able to be consume | LL | fn call(f: F) where F : Fn() { | ^^^^ -note: `into_iter` takes ownership of the receiver `self`, which moves `y` +note: `std::iter::IntoIterator::into_iter` takes ownership of the receiver `self`, which moves `y` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: consider cloning the value if the performance cost is acceptable | diff --git a/tests/ui/codemap_tests/tab_3.stderr b/tests/ui/codemap_tests/tab_3.stderr index 2a0a9e2d48f31..757c92ba9298b 100644 --- a/tests/ui/codemap_tests/tab_3.stderr +++ b/tests/ui/codemap_tests/tab_3.stderr @@ -9,7 +9,7 @@ LL | { LL | println!("{:?}", some_vec); | ^^^^^^^^ value borrowed here after move | -note: `into_iter` takes ownership of the receiver `self`, which moves `some_vec` +note: `std::iter::IntoIterator::into_iter` takes ownership of the receiver `self`, which moves `some_vec` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: you can `clone` the value and consume it, but this might not be your desired behavior | diff --git a/tests/ui/errors/remap-path-prefix-sysroot.with-remap.stderr b/tests/ui/errors/remap-path-prefix-sysroot.with-remap.stderr index 8540f492a662a..558a3d8e34b8b 100644 --- a/tests/ui/errors/remap-path-prefix-sysroot.with-remap.stderr +++ b/tests/ui/errors/remap-path-prefix-sysroot.with-remap.stderr @@ -6,7 +6,7 @@ LL | self.thread.join().unwrap(); | | | move occurs because `self.thread` has type `JoinHandle<()>`, which does not implement the `Copy` trait | -note: `JoinHandle::::join` takes ownership of the receiver `self`, which moves `self.thread` +note: `std::thread::JoinHandle::::join` takes ownership of the receiver `self`, which moves `self.thread` --> remapped/library/std/src/thread/join_handle.rs:LL:COL | LL | pub fn join(self) -> Result { diff --git a/tests/ui/errors/remap-path-prefix-sysroot.without-remap.stderr b/tests/ui/errors/remap-path-prefix-sysroot.without-remap.stderr index 91a3d5b5d6c8a..28c409a50ca7c 100644 --- a/tests/ui/errors/remap-path-prefix-sysroot.without-remap.stderr +++ b/tests/ui/errors/remap-path-prefix-sysroot.without-remap.stderr @@ -6,7 +6,7 @@ LL | self.thread.join().unwrap(); | | | move occurs because `self.thread` has type `JoinHandle<()>`, which does not implement the `Copy` trait | -note: `JoinHandle::::join` takes ownership of the receiver `self`, which moves `self.thread` +note: `std::thread::JoinHandle::::join` takes ownership of the receiver `self`, which moves `self.thread` --> $SRC_DIR_REAL/std/src/thread/join_handle.rs:LL:COL | LL | pub fn join(self) -> Result { diff --git a/tests/ui/loops/issue-82916.stderr b/tests/ui/loops/issue-82916.stderr index 5a5e9c4f0bbeb..0a635836c800c 100644 --- a/tests/ui/loops/issue-82916.stderr +++ b/tests/ui/loops/issue-82916.stderr @@ -9,7 +9,7 @@ LL | for y in x { LL | let z = x; | ^ value used here after move | -note: `into_iter` takes ownership of the receiver `self`, which moves `x` +note: the `for` loop is desugared into a call to `std::iter::IntoIterator::into_iter`, which takes ownership of the receiver `self`, which moves `x` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: consider iterating over a slice of the `Vec`'s content to avoid moving into the `for` loop | diff --git a/tests/ui/moves/move-fn-self-receiver.stderr b/tests/ui/moves/move-fn-self-receiver.stderr index 40a82523c840c..1146828d9c421 100644 --- a/tests/ui/moves/move-fn-self-receiver.stderr +++ b/tests/ui/moves/move-fn-self-receiver.stderr @@ -6,7 +6,7 @@ LL | val.0.into_iter().next(); LL | val.0; | ^^^^^ value used here after move | -note: `into_iter` takes ownership of the receiver `self`, which moves `val.0` +note: `std::iter::IntoIterator::into_iter` takes ownership of the receiver `self`, which moves `val.0` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL = note: move occurs because `val.0` has type `Vec`, which does not implement the `Copy` trait help: you can `clone` the value and consume it, but this might not be your desired behavior diff --git a/tests/ui/moves/moves-based-on-type-access-to-field.stderr b/tests/ui/moves/moves-based-on-type-access-to-field.stderr index 1e656e686fd87..ff2634114e9f0 100644 --- a/tests/ui/moves/moves-based-on-type-access-to-field.stderr +++ b/tests/ui/moves/moves-based-on-type-access-to-field.stderr @@ -8,7 +8,7 @@ LL | consume(x.into_iter().next().unwrap()); LL | touch(&x[0]); | ^ value borrowed here after move | -note: `into_iter` takes ownership of the receiver `self`, which moves `x` +note: `std::iter::IntoIterator::into_iter` takes ownership of the receiver `self`, which moves `x` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: you can `clone` the value and consume it, but this might not be your desired behavior | diff --git a/tests/ui/moves/moves-based-on-type-exprs.stderr b/tests/ui/moves/moves-based-on-type-exprs.stderr index 45f7d4063a593..bdb81d65a4595 100644 --- a/tests/ui/moves/moves-based-on-type-exprs.stderr +++ b/tests/ui/moves/moves-based-on-type-exprs.stderr @@ -160,7 +160,7 @@ LL | let _y = x.into_iter().next().unwrap(); LL | touch(&x); | ^^ value borrowed here after move | -note: `into_iter` takes ownership of the receiver `self`, which moves `x` +note: `std::iter::IntoIterator::into_iter` takes ownership of the receiver `self`, which moves `x` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: you can `clone` the value and consume it, but this might not be your desired behavior | @@ -177,7 +177,7 @@ LL | let _y = [x.into_iter().next().unwrap(); 1]; LL | touch(&x); | ^^ value borrowed here after move | -note: `into_iter` takes ownership of the receiver `self`, which moves `x` +note: `std::iter::IntoIterator::into_iter` takes ownership of the receiver `self`, which moves `x` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: you can `clone` the value and consume it, but this might not be your desired behavior | diff --git a/tests/ui/moves/needs-clone-through-deref.stderr b/tests/ui/moves/needs-clone-through-deref.stderr index 9890ad480a6f0..bcd4b807f91ac 100644 --- a/tests/ui/moves/needs-clone-through-deref.stderr +++ b/tests/ui/moves/needs-clone-through-deref.stderr @@ -6,7 +6,7 @@ LL | for _ in self.clone().into_iter() {} | | | move occurs because value has type `Vec`, which does not implement the `Copy` trait | -note: `into_iter` takes ownership of the receiver `self`, which moves value +note: `std::iter::IntoIterator::into_iter` takes ownership of the receiver `self`, which moves value --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: you can `clone` the value and consume it, but this might not be your desired behavior | diff --git a/tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.stderr b/tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.stderr index bb179e1497b4e..4296dfd2b246e 100644 --- a/tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.stderr +++ b/tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.stderr @@ -8,7 +8,7 @@ LL | foo(r.get_mut()); LL | foo(r.get_mut()); | ^ value used here after move | -note: `Pin::<&'a mut T>::get_mut` takes ownership of the receiver `self`, which moves `r` +note: `std::pin::Pin::<&'a mut T>::get_mut` takes ownership of the receiver `self`, which moves `r` --> $SRC_DIR/core/src/pin.rs:LL:COL help: consider reborrowing the `Pin` instead of moving it | diff --git a/tests/ui/moves/suggest-clone-when-some-obligation-is-unmet.stderr b/tests/ui/moves/suggest-clone-when-some-obligation-is-unmet.stderr index af0f67b7c1c07..c5cb7bf403d5b 100644 --- a/tests/ui/moves/suggest-clone-when-some-obligation-is-unmet.stderr +++ b/tests/ui/moves/suggest-clone-when-some-obligation-is-unmet.stderr @@ -6,7 +6,7 @@ LL | let mut copy: Vec = map.clone().into_values().collect(); | | | move occurs because value has type `HashMap`, which does not implement the `Copy` trait | -note: `HashMap::::into_values` takes ownership of the receiver `self`, which moves value +note: `std::collections::HashMap::::into_values` takes ownership of the receiver `self`, which moves value --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL note: if `Hash128_1` implemented `Clone`, you could clone the value --> $DIR/suggest-clone-when-some-obligation-is-unmet.rs:8:1 diff --git a/tests/ui/suggestions/as-ref-2.stderr b/tests/ui/suggestions/as-ref-2.stderr index b183c8b2faee4..54f06ff2db486 100644 --- a/tests/ui/suggestions/as-ref-2.stderr +++ b/tests/ui/suggestions/as-ref-2.stderr @@ -8,7 +8,7 @@ LL | let _x: Option = foo.map(|s| bar(&s)); LL | let _y = foo; | ^^^ value used here after move | -note: `Option::::map` takes ownership of the receiver `self`, which moves `foo` +note: `std::option::Option::::map` takes ownership of the receiver `self`, which moves `foo` --> $SRC_DIR/core/src/option.rs:LL:COL help: consider calling `.as_ref()` to borrow the value's contents | diff --git a/tests/ui/suggestions/borrow-for-loop-head.stderr b/tests/ui/suggestions/borrow-for-loop-head.stderr index 55fcb44168c49..de425abe85ae5 100644 --- a/tests/ui/suggestions/borrow-for-loop-head.stderr +++ b/tests/ui/suggestions/borrow-for-loop-head.stderr @@ -23,7 +23,7 @@ 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 | -note: `into_iter` takes ownership of the receiver `self`, which moves `a` +note: the `for` loop is desugared into a call to `std::iter::IntoIterator::into_iter`, which takes ownership of the receiver `self`, which moves `a` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: consider iterating over a slice of the `Vec`'s content to avoid moving into the `for` loop | diff --git a/tests/ui/suggestions/for-i-in-vec.stderr b/tests/ui/suggestions/for-i-in-vec.stderr index 64eb4f8bd23ba..ebb463c002679 100644 --- a/tests/ui/suggestions/for-i-in-vec.stderr +++ b/tests/ui/suggestions/for-i-in-vec.stderr @@ -7,7 +7,7 @@ LL | for _ in self.v { | `self.v` moved due to this implicit call to `.into_iter()` | move occurs because `self.v` has type `Vec`, which does not implement the `Copy` trait | -note: `into_iter` takes ownership of the receiver `self`, which moves `self.v` +note: the `for` loop is desugared into a call to `std::iter::IntoIterator::into_iter`, which takes ownership of the receiver `self`, which moves `self.v` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: consider iterating over a slice of the `Vec`'s content to avoid moving into the `for` loop | @@ -45,7 +45,7 @@ LL | for loader in *LOADERS { | 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: `into_iter` takes ownership of the receiver `self`, which moves value +note: the `for` loop is desugared into a call to `std::iter::IntoIterator::into_iter`, which 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 to avoid moving into the `for` loop | diff --git a/tests/ui/suggestions/issue-102972.stderr b/tests/ui/suggestions/issue-102972.stderr index 438f28ad03264..501a5c9efd35e 100644 --- a/tests/ui/suggestions/issue-102972.stderr +++ b/tests/ui/suggestions/issue-102972.stderr @@ -28,7 +28,7 @@ LL | iter.next(); | ^^^^ value borrowed here after move | = note: a for loop advances the iterator for you, the result is stored in `_i` -note: `into_iter` takes ownership of the receiver `self`, which moves `iter` +note: the `for` loop is desugared into a call to `std::iter::IntoIterator::into_iter`, which takes ownership of the receiver `self`, which moves `iter` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: if you want to call `next` on a iterator within the loop, consider using `while let` | @@ -66,7 +66,7 @@ LL | iter.next(); | ^^^^ value borrowed here after move | = note: a for loop advances the iterator for you, the result is stored in its pattern -note: `into_iter` takes ownership of the receiver `self`, which moves `iter` +note: the `for` loop is desugared into a call to `std::iter::IntoIterator::into_iter`, which takes ownership of the receiver `self`, which moves `iter` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: if you want to call `next` on a iterator within the loop, consider using `while let` | diff --git a/tests/ui/suggestions/option-content-move.stderr b/tests/ui/suggestions/option-content-move.stderr index b514622699e73..163c408d219c5 100644 --- a/tests/ui/suggestions/option-content-move.stderr +++ b/tests/ui/suggestions/option-content-move.stderr @@ -6,7 +6,7 @@ LL | if selection.1.unwrap().contains(selection.0) { | | | move occurs because `selection.1` has type `Option`, which does not implement the `Copy` trait | -note: `Option::::unwrap` takes ownership of the receiver `self`, which moves `selection.1` +note: `std::option::Option::::unwrap` takes ownership of the receiver `self`, which moves `selection.1` --> $SRC_DIR/core/src/option.rs:LL:COL help: consider calling `.as_ref()` to borrow the value's contents | @@ -29,7 +29,7 @@ LL | if selection.1.unwrap().contains(selection.0) { | | | move occurs because `selection.1` has type `Result`, which does not implement the `Copy` trait | -note: `Result::::unwrap` takes ownership of the receiver `self`, which moves `selection.1` +note: `std::result::Result::::unwrap` takes ownership of the receiver `self`, which moves `selection.1` --> $SRC_DIR/core/src/result.rs:LL:COL help: consider calling `.as_ref()` to borrow the value's contents |