Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 10dccdc

Browse files
committedMar 9, 2022
Auto merge of #94515 - estebank:tweak-move-error, r=davidtwco
Tweak move error Point at method definition that causes type to be consumed. Fix #94056.
2 parents 6045c34 + 9875277 commit 10dccdc

21 files changed

+289
-242
lines changed
 

‎compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 15 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use either::Either;
2-
use rustc_const_eval::util::{CallDesugaringKind, CallKind};
2+
use rustc_const_eval::util::CallKind;
33
use rustc_data_structures::fx::FxHashSet;
44
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
55
use rustc_hir as hir;
@@ -17,7 +17,7 @@ use rustc_middle::ty::{
1717
};
1818
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
1919
use rustc_span::symbol::sym;
20-
use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
20+
use rustc_span::{BytePos, MultiSpan, Span};
2121
use rustc_trait_selection::infer::InferCtxtExt;
2222
use rustc_trait_selection::traits::TraitEngineExt as _;
2323

@@ -195,144 +195,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
195195
is_loop_move = true;
196196
}
197197

198-
if let UseSpans::FnSelfUse { var_span, fn_call_span, fn_span, kind } = move_spans {
199-
let place_name = self
200-
.describe_place(moved_place.as_ref())
201-
.map(|n| format!("`{}`", n))
202-
.unwrap_or_else(|| "value".to_owned());
203-
match kind {
204-
CallKind::FnCall { fn_trait_id, .. }
205-
if Some(fn_trait_id) == self.infcx.tcx.lang_items().fn_once_trait() =>
206-
{
207-
err.span_label(
208-
fn_call_span,
209-
&format!(
210-
"{} {}moved due to this call{}",
211-
place_name, partially_str, loop_message
212-
),
213-
);
214-
err.span_note(
215-
var_span,
216-
"this value implements `FnOnce`, which causes it to be moved when called",
217-
);
218-
}
219-
CallKind::Operator { self_arg, .. } => {
220-
let self_arg = self_arg.unwrap();
221-
err.span_label(
222-
fn_call_span,
223-
&format!(
224-
"{} {}moved due to usage in operator{}",
225-
place_name, partially_str, loop_message
226-
),
227-
);
228-
if self.fn_self_span_reported.insert(fn_span) {
229-
err.span_note(
230-
// Check whether the source is accessible
231-
if self
232-
.infcx
233-
.tcx
234-
.sess
235-
.source_map()
236-
.span_to_snippet(self_arg.span)
237-
.is_ok()
238-
{
239-
self_arg.span
240-
} else {
241-
fn_call_span
242-
},
243-
"calling this operator moves the left-hand side",
244-
);
245-
}
246-
}
247-
CallKind::Normal { self_arg, desugaring, is_option_or_result } => {
248-
let self_arg = self_arg.unwrap();
249-
if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring {
250-
err.span_label(
251-
fn_call_span,
252-
&format!(
253-
"{} {}moved due to this implicit call to `.into_iter()`{}",
254-
place_name, partially_str, loop_message
255-
),
256-
);
257-
let sess = self.infcx.tcx.sess;
258-
let ty = used_place.ty(self.body, self.infcx.tcx).ty;
259-
// If we have a `&mut` ref, we need to reborrow.
260-
if let ty::Ref(_, _, hir::Mutability::Mut) = ty.kind() {
261-
// If we are in a loop this will be suggested later.
262-
if !is_loop_move {
263-
err.span_suggestion_verbose(
264-
move_span.shrink_to_lo(),
265-
&format!(
266-
"consider creating a fresh reborrow of {} here",
267-
self.describe_place(moved_place.as_ref())
268-
.map(|n| format!("`{}`", n))
269-
.unwrap_or_else(
270-
|| "the mutable reference".to_string()
271-
),
272-
),
273-
"&mut *".to_string(),
274-
Applicability::MachineApplicable,
275-
);
276-
}
277-
} else if let Ok(snippet) =
278-
sess.source_map().span_to_snippet(move_span)
279-
{
280-
err.span_suggestion(
281-
move_span,
282-
"consider borrowing to avoid moving into the for loop",
283-
format!("&{}", snippet),
284-
Applicability::MaybeIncorrect,
285-
);
286-
}
287-
} else {
288-
err.span_label(
289-
fn_call_span,
290-
&format!(
291-
"{} {}moved due to this method call{}",
292-
place_name, partially_str, loop_message
293-
),
294-
);
295-
}
296-
if is_option_or_result && maybe_reinitialized_locations.is_empty() {
297-
err.span_suggestion_verbose(
298-
fn_call_span.shrink_to_lo(),
299-
"consider calling `.as_ref()` to borrow the type's contents",
300-
"as_ref().".to_string(),
301-
Applicability::MachineApplicable,
302-
);
303-
}
304-
// Avoid pointing to the same function in multiple different
305-
// error messages.
306-
if span != DUMMY_SP && self.fn_self_span_reported.insert(self_arg.span)
307-
{
308-
err.span_note(
309-
self_arg.span,
310-
&format!("this function takes ownership of the receiver `self`, which moves {}", place_name)
311-
);
312-
}
313-
}
314-
// Other desugarings takes &self, which cannot cause a move
315-
_ => unreachable!(),
316-
}
317-
} else {
318-
err.span_label(
319-
move_span,
320-
format!("value {}moved{} here{}", partially_str, move_msg, loop_message),
321-
);
322-
// If the move error occurs due to a loop, don't show
323-
// another message for the same span
324-
if loop_message.is_empty() {
325-
move_spans.var_span_label(
326-
&mut err,
327-
format!(
328-
"variable {}moved due to use{}",
329-
partially_str,
330-
move_spans.describe()
331-
),
332-
"moved",
333-
);
334-
}
335-
}
198+
self.explain_captures(
199+
&mut err,
200+
span,
201+
move_span,
202+
move_spans,
203+
*moved_place,
204+
Some(used_place),
205+
partially_str,
206+
loop_message,
207+
move_msg,
208+
is_loop_move,
209+
maybe_reinitialized_locations.is_empty(),
210+
);
336211

337212
if let (UseSpans::PatUse(span), []) =
338213
(move_spans, &maybe_reinitialized_locations[..])

‎compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 174 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
//! Borrow checker diagnostics.
22
3-
use rustc_const_eval::util::call_kind;
4-
use rustc_errors::Diagnostic;
3+
use rustc_const_eval::util::{call_kind, CallDesugaringKind};
4+
use rustc_errors::{Applicability, Diagnostic};
55
use rustc_hir as hir;
66
use rustc_hir::def::Namespace;
77
use rustc_hir::def_id::DefId;
88
use rustc_hir::GeneratorKind;
9+
use rustc_infer::infer::TyCtxtInferExt;
910
use rustc_middle::mir::{
1011
AggregateKind, Constant, FakeReadCause, Field, Local, LocalInfo, LocalKind, Location, Operand,
1112
Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
1213
};
1314
use rustc_middle::ty::print::Print;
1415
use rustc_middle::ty::{self, DefIdTree, Instance, Ty, TyCtxt};
1516
use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult};
16-
use rustc_span::{symbol::sym, Span};
17+
use rustc_span::{symbol::sym, Span, DUMMY_SP};
1718
use rustc_target::abi::VariantIdx;
19+
use rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions;
1820

1921
use super::borrow_set::BorrowData;
2022
use super::MirBorrowckCtxt;
@@ -482,9 +484,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
482484
BorrowedContentSource::DerefSharedRef
483485
}
484486
}
485-
}
486487

487-
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
488488
/// Return the name of the provided `Ty` (that must be a reference) with a synthesized lifetime
489489
/// name where required.
490490
pub(super) fn get_name_for_ty(&self, ty: Ty<'tcx>, counter: usize) -> String {
@@ -995,4 +995,173 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
995995
let span = self.body.source_info(borrow.reserve_location).span;
996996
self.borrow_spans(span, borrow.reserve_location)
997997
}
998+
999+
fn explain_captures(
1000+
&mut self,
1001+
err: &mut Diagnostic,
1002+
span: Span,
1003+
move_span: Span,
1004+
move_spans: UseSpans<'tcx>,
1005+
moved_place: Place<'tcx>,
1006+
used_place: Option<PlaceRef<'tcx>>,
1007+
partially_str: &str,
1008+
loop_message: &str,
1009+
move_msg: &str,
1010+
is_loop_move: bool,
1011+
maybe_reinitialized_locations_is_empty: bool,
1012+
) {
1013+
if let UseSpans::FnSelfUse { var_span, fn_call_span, fn_span, kind } = move_spans {
1014+
let place_name = self
1015+
.describe_place(moved_place.as_ref())
1016+
.map(|n| format!("`{}`", n))
1017+
.unwrap_or_else(|| "value".to_owned());
1018+
match kind {
1019+
CallKind::FnCall { fn_trait_id, .. }
1020+
if Some(fn_trait_id) == self.infcx.tcx.lang_items().fn_once_trait() =>
1021+
{
1022+
err.span_label(
1023+
fn_call_span,
1024+
&format!(
1025+
"{} {}moved due to this call{}",
1026+
place_name, partially_str, loop_message
1027+
),
1028+
);
1029+
err.span_note(
1030+
var_span,
1031+
"this value implements `FnOnce`, which causes it to be moved when called",
1032+
);
1033+
}
1034+
CallKind::Operator { self_arg, .. } => {
1035+
let self_arg = self_arg.unwrap();
1036+
err.span_label(
1037+
fn_call_span,
1038+
&format!(
1039+
"{} {}moved due to usage in operator{}",
1040+
place_name, partially_str, loop_message
1041+
),
1042+
);
1043+
if self.fn_self_span_reported.insert(fn_span) {
1044+
err.span_note(
1045+
// Check whether the source is accessible
1046+
if self
1047+
.infcx
1048+
.tcx
1049+
.sess
1050+
.source_map()
1051+
.span_to_snippet(self_arg.span)
1052+
.is_ok()
1053+
{
1054+
self_arg.span
1055+
} else {
1056+
fn_call_span
1057+
},
1058+
"calling this operator moves the left-hand side",
1059+
);
1060+
}
1061+
}
1062+
CallKind::Normal { self_arg, desugaring, is_option_or_result } => {
1063+
let self_arg = self_arg.unwrap();
1064+
if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring {
1065+
let ty = moved_place.ty(self.body, self.infcx.tcx).ty;
1066+
let suggest = match self.infcx.tcx.get_diagnostic_item(sym::IntoIterator) {
1067+
Some(def_id) => self.infcx.tcx.infer_ctxt().enter(|infcx| {
1068+
type_known_to_meet_bound_modulo_regions(
1069+
&infcx,
1070+
self.param_env,
1071+
infcx.tcx.mk_imm_ref(
1072+
infcx.tcx.lifetimes.re_erased,
1073+
infcx.tcx.erase_regions(ty),
1074+
),
1075+
def_id,
1076+
DUMMY_SP,
1077+
)
1078+
}),
1079+
_ => false,
1080+
};
1081+
if suggest {
1082+
err.span_suggestion_verbose(
1083+
move_span.shrink_to_lo(),
1084+
&format!(
1085+
"consider iterating over a slice of the `{}`'s content to \
1086+
avoid moving into the `for` loop",
1087+
ty,
1088+
),
1089+
"&".to_string(),
1090+
Applicability::MaybeIncorrect,
1091+
);
1092+
}
1093+
1094+
err.span_label(
1095+
fn_call_span,
1096+
&format!(
1097+
"{} {}moved due to this implicit call to `.into_iter()`{}",
1098+
place_name, partially_str, loop_message
1099+
),
1100+
);
1101+
// If we have a `&mut` ref, we need to reborrow.
1102+
if let Some(ty::Ref(_, _, hir::Mutability::Mut)) = used_place
1103+
.map(|used_place| used_place.ty(self.body, self.infcx.tcx).ty.kind())
1104+
{
1105+
// If we are in a loop this will be suggested later.
1106+
if !is_loop_move {
1107+
err.span_suggestion_verbose(
1108+
move_span.shrink_to_lo(),
1109+
&format!(
1110+
"consider creating a fresh reborrow of {} here",
1111+
self.describe_place(moved_place.as_ref())
1112+
.map(|n| format!("`{}`", n))
1113+
.unwrap_or_else(|| "the mutable reference".to_string()),
1114+
),
1115+
"&mut *".to_string(),
1116+
Applicability::MachineApplicable,
1117+
);
1118+
}
1119+
}
1120+
} else {
1121+
err.span_label(
1122+
fn_call_span,
1123+
&format!(
1124+
"{} {}moved due to this method call{}",
1125+
place_name, partially_str, loop_message
1126+
),
1127+
);
1128+
}
1129+
if is_option_or_result && maybe_reinitialized_locations_is_empty {
1130+
err.span_suggestion_verbose(
1131+
fn_call_span.shrink_to_lo(),
1132+
"consider calling `.as_ref()` to borrow the type's contents",
1133+
"as_ref().".to_string(),
1134+
Applicability::MachineApplicable,
1135+
);
1136+
}
1137+
// Avoid pointing to the same function in multiple different
1138+
// error messages.
1139+
if span != DUMMY_SP && self.fn_self_span_reported.insert(self_arg.span) {
1140+
err.span_note(
1141+
self_arg.span,
1142+
&format!("this function takes ownership of the receiver `self`, which moves {}", place_name)
1143+
);
1144+
}
1145+
}
1146+
// Other desugarings takes &self, which cannot cause a move
1147+
_ => {}
1148+
}
1149+
} else {
1150+
if move_span != span || !loop_message.is_empty() {
1151+
err.span_label(
1152+
move_span,
1153+
format!("value {}moved{} here{}", partially_str, move_msg, loop_message),
1154+
);
1155+
}
1156+
// If the move error occurs due to a loop, don't show
1157+
// another message for the same span
1158+
if loop_message.is_empty() {
1159+
move_spans.var_span_label(
1160+
err,
1161+
format!("variable {}moved due to use{}", partially_str, move_spans.describe()),
1162+
"moved",
1163+
);
1164+
}
1165+
}
1166+
}
9981167
}

‎compiler/rustc_borrowck/src/diagnostics/move_errors.rs

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
use rustc_const_eval::util::CallDesugaringKind;
21
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
3-
use rustc_infer::infer::TyCtxtInferExt;
42
use rustc_middle::mir::*;
53
use rustc_middle::ty;
64
use rustc_mir_dataflow::move_paths::{
75
IllegalMoveOrigin, IllegalMoveOriginKind, LookupResult, MoveError, MovePathIndex,
86
};
9-
use rustc_span::{sym, Span, DUMMY_SP};
10-
use rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions;
7+
use rustc_span::{sym, Span};
118

12-
use crate::diagnostics::{CallKind, UseSpans};
9+
use crate::diagnostics::UseSpans;
1310
use crate::prefixes::PrefixSet;
1411
use crate::MirBorrowckCtxt;
1512

@@ -409,34 +406,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
409406
".as_ref()".to_string(),
410407
Applicability::MaybeIncorrect,
411408
);
412-
} else if let Some(UseSpans::FnSelfUse {
413-
kind:
414-
CallKind::Normal { desugaring: Some((CallDesugaringKind::ForLoopIntoIter, _)), .. },
415-
..
416-
}) = use_spans
417-
{
418-
let suggest = match self.infcx.tcx.get_diagnostic_item(sym::IntoIterator) {
419-
Some(def_id) => self.infcx.tcx.infer_ctxt().enter(|infcx| {
420-
type_known_to_meet_bound_modulo_regions(
421-
&infcx,
422-
self.param_env,
423-
infcx
424-
.tcx
425-
.mk_imm_ref(infcx.tcx.lifetimes.re_erased, infcx.tcx.erase_regions(ty)),
426-
def_id,
427-
DUMMY_SP,
428-
)
429-
}),
430-
_ => false,
431-
};
432-
if suggest {
433-
err.span_suggestion_verbose(
434-
span.shrink_to_lo(),
435-
&format!("consider iterating over a slice of the `{}`'s content", ty),
436-
"&".to_string(),
437-
Applicability::MaybeIncorrect,
438-
);
439-
}
409+
} else if let Some(use_spans) = use_spans {
410+
self.explain_captures(
411+
&mut err, span, span, use_spans, move_place, None, "", "", "", false, true,
412+
);
440413
}
441414
err
442415
}
@@ -491,11 +464,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
491464
self.note_type_does_not_implement_copy(err, &place_desc, place_ty, Some(span), "");
492465

493466
use_spans.args_span_label(err, format!("move out of {} occurs here", place_desc));
494-
use_spans.var_span_label(
495-
err,
496-
format!("move occurs due to use{}", use_spans.describe()),
497-
"moved",
498-
);
499467
}
500468
}
501469
}

‎src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.edition.stderr

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ error[E0507]: cannot move out of `foo` in pattern guard
22
--> $DIR/borrowck-feature-nll-overrides-migrate.rs:22:18
33
|
44
LL | (|| { let bar = foo; bar.take() })();
5-
| ^^ ---
6-
| | |
7-
| | move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
8-
| | move occurs due to use in closure
5+
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
6+
| |
97
| move out of `foo` occurs here
108
|
119
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard

‎src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.zflag.stderr

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ error[E0507]: cannot move out of `foo` in pattern guard
22
--> $DIR/borrowck-feature-nll-overrides-migrate.rs:22:18
33
|
44
LL | (|| { let bar = foo; bar.take() })();
5-
| ^^ ---
6-
| | |
7-
| | move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
8-
| | move occurs due to use in closure
5+
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
6+
| |
97
| move out of `foo` occurs here
108
|
119
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard

‎src/test/ui/borrowck/borrowck-move-by-capture.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ LL | let _g = to_fn_mut(|| {
88
LL | | let _h = to_fn_once(move || -> isize { *bar });
99
| | ^^^^^^^^^^^^^^^^ ----
1010
| | | |
11+
| | | variable moved due to use in closure
1112
| | | move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
12-
| | | move occurs due to use in closure
1313
| | move out of `bar` occurs here
1414
LL | | });
1515
| |_____- captured by this `FnMut` closure

‎src/test/ui/borrowck/borrowck-move-out-of-overloaded-auto-deref.stderr

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@ error[E0507]: cannot move out of an `Rc`
22
--> $DIR/borrowck-move-out-of-overloaded-auto-deref.rs:4:14
33
|
44
LL | let _x = Rc::new(vec![1, 2]).into_iter();
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `Vec<i32>`, which does not implement the `Copy` trait
5+
| ^^^^^^^^^^^^^^^^^^^^-----------
6+
| | |
7+
| | value moved due to this method call
8+
| move occurs because value has type `Vec<i32>`, which does not implement the `Copy` trait
9+
|
10+
note: this function takes ownership of the receiver `self`, which moves value
11+
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
12+
|
13+
LL | fn into_iter(self) -> Self::IntoIter;
14+
| ^^^^
615

716
error: aborting due to previous error
817

‎src/test/ui/borrowck/issue-27282-mutation-in-guard.stderr

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ error[E0507]: cannot move out of `foo` in pattern guard
22
--> $DIR/issue-27282-mutation-in-guard.rs:6:18
33
|
44
LL | (|| { let bar = foo; bar.take() })();
5-
| ^^ ---
6-
| | |
7-
| | move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
8-
| | move occurs due to use in closure
5+
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
6+
| |
97
| move out of `foo` occurs here
108
|
119
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard

‎src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,18 @@ LL | let y = vec![format!("World")];
66
LL | call(|| {
77
| __________-
88
LL | | y.into_iter();
9-
| | ^ move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait
9+
| | ^ ----------- `y` moved due to this method call
10+
| | |
11+
| | move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait
1012
LL | |
1113
LL | | });
1214
| |_____- captured by this `Fn` closure
15+
|
16+
note: this function takes ownership of the receiver `self`, which moves `y`
17+
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
18+
|
19+
LL | fn into_iter(self) -> Self::IntoIter;
20+
| ^^^^
1321

1422
error: aborting due to previous error
1523

‎src/test/ui/error-codes/E0507.stderr

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@ error[E0507]: cannot move out of dereference of `Ref<'_, TheDarkKnight>`
22
--> $DIR/E0507.rs:12:5
33
|
44
LL | x.borrow().nothing_is_true();
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `TheDarkKnight`, which does not implement the `Copy` trait
5+
| ^^^^^^^^^^^-----------------
6+
| | |
7+
| | value moved due to this method call
8+
| move occurs because value has type `TheDarkKnight`, which does not implement the `Copy` trait
9+
|
10+
note: this function takes ownership of the receiver `self`, which moves value
11+
--> $DIR/E0507.rs:6:24
12+
|
13+
LL | fn nothing_is_true(self) {}
14+
| ^^^^
615

716
error: aborting due to previous error
817

‎src/test/ui/issues/issue-27282-move-ref-mut-into-guard.stderr

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ error[E0507]: cannot move out of `foo` in pattern guard
22
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:9:19
33
|
44
LL | if { (|| { let bar = foo; bar.take() })(); false } => {},
5-
| ^^ ---
6-
| | |
7-
| | move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
8-
| | move occurs due to use in closure
5+
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
6+
| |
97
| move out of `foo` occurs here
108
|
119
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard

‎src/test/ui/issues/issue-61108.stderr

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ error[E0382]: borrow of moved value: `bad_letters`
44
LL | let mut bad_letters = vec!['e', 't', 'o', 'i'];
55
| --------------- move occurs because `bad_letters` has type `Vec<char>`, which does not implement the `Copy` trait
66
LL | for l in bad_letters {
7-
| -----------
8-
| |
9-
| `bad_letters` moved due to this implicit call to `.into_iter()`
10-
| help: consider borrowing to avoid moving into the for loop: `&bad_letters`
7+
| ----------- `bad_letters` moved due to this implicit call to `.into_iter()`
118
...
129
LL | bad_letters.push('s');
1310
| ^^^^^^^^^^^^^^^^^^^^^ value borrowed here after move
@@ -17,6 +14,10 @@ note: this function takes ownership of the receiver `self`, which moves `bad_let
1714
|
1815
LL | fn into_iter(self) -> Self::IntoIter;
1916
| ^^^^
17+
help: consider iterating over a slice of the `Vec<char>`'s content to avoid moving into the `for` loop
18+
|
19+
LL | for l in &bad_letters {
20+
| +
2021

2122
error: aborting due to previous error
2223

‎src/test/ui/issues/issue-64559.stderr

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ error[E0382]: use of moved value: `orig`
44
LL | let orig = vec![true];
55
| ---- move occurs because `orig` has type `Vec<bool>`, which does not implement the `Copy` trait
66
LL | for _val in orig {}
7-
| ----
8-
| |
9-
| `orig` moved due to this implicit call to `.into_iter()`
10-
| help: consider borrowing to avoid moving into the for loop: `&orig`
7+
| ---- `orig` moved due to this implicit call to `.into_iter()`
118
LL | let _closure = || orig;
129
| ^^ ---- use occurs due to use in closure
1310
| |
@@ -18,6 +15,10 @@ note: this function takes ownership of the receiver `self`, which moves `orig`
1815
|
1916
LL | fn into_iter(self) -> Self::IntoIter;
2017
| ^^^^
18+
help: consider iterating over a slice of the `Vec<bool>`'s content to avoid moving into the `for` loop
19+
|
20+
LL | for _val in &orig {}
21+
| +
2122

2223
error: aborting due to previous error
2324

‎src/test/ui/loops/issue-82916.stderr

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ error[E0382]: use of moved value: `x`
44
LL | fn foo(x: Vec<S>) {
55
| - move occurs because `x` has type `Vec<S>`, which does not implement the `Copy` trait
66
LL | for y in x {
7-
| -
8-
| |
9-
| `x` moved due to this implicit call to `.into_iter()`
10-
| help: consider borrowing to avoid moving into the for loop: `&x`
7+
| - `x` moved due to this implicit call to `.into_iter()`
118
...
129
LL | let z = x;
1310
| ^ value used here after move
@@ -17,6 +14,10 @@ note: this function takes ownership of the receiver `self`, which moves `x`
1714
|
1815
LL | fn into_iter(self) -> Self::IntoIter;
1916
| ^^^^
17+
help: consider iterating over a slice of the `Vec<S>`'s content to avoid moving into the `for` loop
18+
|
19+
LL | for y in &x {
20+
| +
2021

2122
error: aborting due to previous error
2223

‎src/test/ui/moves/issue-46099-move-in-macro.stderr

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ error[E0382]: use of moved value: `b`
44
LL | let b = Box::new(true);
55
| - move occurs because `b` has type `Box<bool>`, which does not implement the `Copy` trait
66
LL | test!({b});
7-
| ^
8-
| |
9-
| value moved here
10-
| value used here after move
7+
| ^ value used here after move
118

129
error: aborting due to previous error
1310

‎src/test/ui/moves/move-fn-self-receiver.stderr

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,14 @@ error[E0382]: use of moved value: `implicit_into_iter`
119119
LL | let implicit_into_iter = vec![true];
120120
| ------------------ move occurs because `implicit_into_iter` has type `Vec<bool>`, which does not implement the `Copy` trait
121121
LL | for _val in implicit_into_iter {}
122-
| ------------------
123-
| |
124-
| `implicit_into_iter` moved due to this implicit call to `.into_iter()`
125-
| help: consider borrowing to avoid moving into the for loop: `&implicit_into_iter`
122+
| ------------------ `implicit_into_iter` moved due to this implicit call to `.into_iter()`
126123
LL | implicit_into_iter;
127124
| ^^^^^^^^^^^^^^^^^^ value used here after move
125+
|
126+
help: consider iterating over a slice of the `Vec<bool>`'s content to avoid moving into the `for` loop
127+
|
128+
LL | for _val in &implicit_into_iter {}
129+
| +
128130

129131
error[E0382]: use of moved value: `explicit_into_iter`
130132
--> $DIR/move-fn-self-receiver.rs:67:5

‎src/test/ui/moves/move-in-guard-2.stderr

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ LL | let x: Box<_> = Box::new(1);
55
| - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
66
...
77
LL | (_, 2) if take(x) => (),
8-
| ^
9-
| |
10-
| value moved here
11-
| value used here after move
8+
| ^ value used here after move
129

1310
error: aborting due to previous error
1411

‎src/test/ui/nll/match-guards-always-borrow.stderr

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ error[E0507]: cannot move out of `foo` in pattern guard
22
--> $DIR/match-guards-always-borrow.rs:8:14
33
|
44
LL | (|| { let bar = foo; bar.take() })();
5-
| ^^ ---
6-
| | |
7-
| | move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
8-
| | move occurs due to use in closure
5+
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
6+
| |
97
| move out of `foo` occurs here
108
|
119
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard

‎src/test/ui/suggestions/borrow-for-loop-head.stderr

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,17 @@ LL | let a = vec![1, 2, 3];
1313
| - move occurs because `a` has type `Vec<i32>`, which does not implement the `Copy` trait
1414
LL | for i in &a {
1515
LL | for j in a {
16-
| ^
17-
| |
18-
| `a` moved due to this implicit call to `.into_iter()`, in previous iteration of loop
19-
| help: consider borrowing to avoid moving into the for loop: `&a`
16+
| ^ `a` moved due to this implicit call to `.into_iter()`, in previous iteration of loop
2017
|
2118
note: this function takes ownership of the receiver `self`, which moves `a`
2219
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
2320
|
2421
LL | fn into_iter(self) -> Self::IntoIter;
2522
| ^^^^
23+
help: consider iterating over a slice of the `Vec<i32>`'s content to avoid moving into the `for` loop
24+
|
25+
LL | for j in &a {
26+
| +
2627

2728
error: aborting due to 2 previous errors
2829

‎src/test/ui/suggestions/for-i-in-vec.stderr

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@ error[E0507]: cannot move out of `self.v` which is behind a shared reference
22
--> $DIR/for-i-in-vec.rs:11:18
33
|
44
LL | for _ in self.v {
5-
| ^^^^^^ move occurs because `self.v` has type `Vec<u32>`, which does not implement the `Copy` trait
5+
| ^^^^^^
6+
| |
7+
| `self.v` moved due to this implicit call to `.into_iter()`
8+
| move occurs because `self.v` has type `Vec<u32>`, which does not implement the `Copy` trait
69
|
7-
help: consider iterating over a slice of the `Vec<u32>`'s content
10+
note: this function takes ownership of the receiver `self`, which moves `self.v`
11+
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
12+
|
13+
LL | fn into_iter(self) -> Self::IntoIter;
14+
| ^^^^
15+
help: consider iterating over a slice of the `Vec<u32>`'s content to avoid moving into the `for` loop
816
|
917
LL | for _ in &self.v {
1018
| +
@@ -13,9 +21,12 @@ error[E0507]: cannot move out of `self.h` which is behind a shared reference
1321
--> $DIR/for-i-in-vec.rs:13:18
1422
|
1523
LL | for _ in self.h {
16-
| ^^^^^^ move occurs because `self.h` has type `HashMap<i32, i32>`, which does not implement the `Copy` trait
24+
| ^^^^^^
25+
| |
26+
| `self.h` moved due to this implicit call to `.into_iter()`
27+
| move occurs because `self.h` has type `HashMap<i32, i32>`, which does not implement the `Copy` trait
1728
|
18-
help: consider iterating over a slice of the `HashMap<i32, i32>`'s content
29+
help: consider iterating over a slice of the `HashMap<i32, i32>`'s content to avoid moving into the `for` loop
1930
|
2031
LL | for _ in &self.h {
2132
| +
@@ -24,9 +35,17 @@ error[E0507]: cannot move out of a shared reference
2435
--> $DIR/for-i-in-vec.rs:21:19
2536
|
2637
LL | for loader in *LOADERS {
27-
| ^^^^^^^^ move occurs because value has type `Vec<&u8>`, which does not implement the `Copy` trait
38+
| ^^^^^^^^
39+
| |
40+
| value moved due to this implicit call to `.into_iter()`
41+
| move occurs because value has type `Vec<&u8>`, which does not implement the `Copy` trait
42+
|
43+
note: this function takes ownership of the receiver `self`, which moves value
44+
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
2845
|
29-
help: consider iterating over a slice of the `Vec<&u8>`'s content
46+
LL | fn into_iter(self) -> Self::IntoIter;
47+
| ^^^^
48+
help: consider iterating over a slice of the `Vec<&u8>`'s content to avoid moving into the `for` loop
3049
|
3150
LL | for loader in &*LOADERS {
3251
| +

‎src/test/ui/suggestions/option-content-move2.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ LL | |
1212
LL | | var = Some(NotCopyable);
1313
| | ---
1414
| | |
15+
| | variable moved due to use in closure
1516
| | move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
16-
| | move occurs due to use in closure
1717
LL | | }
1818
LL | | });
1919
| |_____- captured by this `FnMut` closure

0 commit comments

Comments
 (0)
Please sign in to comment.