Rollup merge of #144200 - estebank:dont-point-at-closure, r=lcnr
Tweak output for non-`Clone` values moved into closures
When we encounter a non-`Clone` value being moved into a closure, try to find the corresponding type of the binding being moved, if it is a `let`-binding or a function parameter. If any of those cases, we point at them with the note explaining that the type is not `Copy`, instead of giving that label to the place where it is captured. When it is a `let`-binding with no explicit type, we point at the initializer (if it fits in a single line).
```
error[E0507]: cannot move out of `foo`, a captured variable in an `Fn` closure
--> f111.rs:14:25
|
13 | fn do_stuff(foo: Option<Foo>) {
| --- ----------- move occurs because `foo` has type `Option<Foo>`, which does not implement the `Copy` trait
| |
| captured outer variable
14 | require_fn_trait(|| async {
| -- ^^^^^ `foo` is moved here
| |
| captured by this `Fn` closure
15 | if foo.map_or(false, |f| f.foo()) {
| --- variable moved due to use in coroutine
```
instead of
```
error[E0507]: cannot move out of `foo`, a captured variable in an `Fn` closure
--> f111.rs:14:25
|
13 | fn do_stuff(foo: Option<Foo>) {
| --- captured outer variable
14 | require_fn_trait(|| async {
| -- ^^^^^ `foo` is moved here
| |
| captured by this `Fn` closure
15 | if foo.map_or(false, |f| f.foo()) {
| ---
| |
| variable moved due to use in coroutine
| move occurs because `foo` has type `Option<Foo>`, which does not implement the `Copy` trait
```
This commit is contained in:
@@ -115,10 +115,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||||||
fn append_to_grouped_errors(
|
fn append_to_grouped_errors(
|
||||||
&self,
|
&self,
|
||||||
grouped_errors: &mut Vec<GroupedMoveError<'tcx>>,
|
grouped_errors: &mut Vec<GroupedMoveError<'tcx>>,
|
||||||
error: MoveError<'tcx>,
|
MoveError { place: original_path, location, kind }: MoveError<'tcx>,
|
||||||
) {
|
) {
|
||||||
let MoveError { place: original_path, location, kind } = error;
|
|
||||||
|
|
||||||
// Note: that the only time we assign a place isn't a temporary
|
// Note: that the only time we assign a place isn't a temporary
|
||||||
// to a user variable is when initializing it.
|
// to a user variable is when initializing it.
|
||||||
// If that ever stops being the case, then the ever initialized
|
// If that ever stops being the case, then the ever initialized
|
||||||
@@ -251,54 +249,47 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn report(&mut self, error: GroupedMoveError<'tcx>) {
|
fn report(&mut self, error: GroupedMoveError<'tcx>) {
|
||||||
let (mut err, err_span) = {
|
let (span, use_spans, original_path, kind) = match error {
|
||||||
let (span, use_spans, original_path, kind) = match error {
|
GroupedMoveError::MovesFromPlace { span, original_path, ref kind, .. }
|
||||||
GroupedMoveError::MovesFromPlace { span, original_path, ref kind, .. }
|
| GroupedMoveError::MovesFromValue { span, original_path, ref kind, .. } => {
|
||||||
| GroupedMoveError::MovesFromValue { span, original_path, ref kind, .. } => {
|
(span, None, original_path, kind)
|
||||||
(span, None, original_path, kind)
|
}
|
||||||
}
|
GroupedMoveError::OtherIllegalMove { use_spans, original_path, ref kind } => {
|
||||||
GroupedMoveError::OtherIllegalMove { use_spans, original_path, ref kind } => {
|
(use_spans.args_or_use(), Some(use_spans), original_path, kind)
|
||||||
(use_spans.args_or_use(), Some(use_spans), original_path, kind)
|
}
|
||||||
}
|
};
|
||||||
};
|
debug!(
|
||||||
debug!(
|
"report: original_path={:?} span={:?}, kind={:?} \
|
||||||
"report: original_path={:?} span={:?}, kind={:?} \
|
original_path.is_upvar_field_projection={:?}",
|
||||||
original_path.is_upvar_field_projection={:?}",
|
original_path,
|
||||||
original_path,
|
span,
|
||||||
span,
|
kind,
|
||||||
kind,
|
self.is_upvar_field_projection(original_path.as_ref())
|
||||||
self.is_upvar_field_projection(original_path.as_ref())
|
);
|
||||||
);
|
if self.has_ambiguous_copy(original_path.ty(self.body, self.infcx.tcx).ty) {
|
||||||
if self.has_ambiguous_copy(original_path.ty(self.body, self.infcx.tcx).ty) {
|
// If the type may implement Copy, skip the error.
|
||||||
// If the type may implement Copy, skip the error.
|
// It's an error with the Copy implementation (e.g. duplicate Copy) rather than borrow check
|
||||||
// It's an error with the Copy implementation (e.g. duplicate Copy) rather than borrow check
|
self.dcx()
|
||||||
self.dcx().span_delayed_bug(
|
.span_delayed_bug(span, "Type may implement copy, but there is no other error.");
|
||||||
span,
|
return;
|
||||||
"Type may implement copy, but there is no other error.",
|
}
|
||||||
);
|
let mut err = match kind {
|
||||||
return;
|
&IllegalMoveOriginKind::BorrowedContent { target_place } => self
|
||||||
|
.report_cannot_move_from_borrowed_content(
|
||||||
|
original_path,
|
||||||
|
target_place,
|
||||||
|
span,
|
||||||
|
use_spans,
|
||||||
|
),
|
||||||
|
&IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
|
||||||
|
self.cannot_move_out_of_interior_of_drop(span, ty)
|
||||||
|
}
|
||||||
|
&IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } => {
|
||||||
|
self.cannot_move_out_of_interior_noncopy(span, ty, Some(is_index))
|
||||||
}
|
}
|
||||||
(
|
|
||||||
match kind {
|
|
||||||
&IllegalMoveOriginKind::BorrowedContent { target_place } => self
|
|
||||||
.report_cannot_move_from_borrowed_content(
|
|
||||||
original_path,
|
|
||||||
target_place,
|
|
||||||
span,
|
|
||||||
use_spans,
|
|
||||||
),
|
|
||||||
&IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
|
|
||||||
self.cannot_move_out_of_interior_of_drop(span, ty)
|
|
||||||
}
|
|
||||||
&IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } => {
|
|
||||||
self.cannot_move_out_of_interior_noncopy(span, ty, Some(is_index))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
span,
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.add_move_hints(error, &mut err, err_span);
|
self.add_move_hints(error, &mut err, span);
|
||||||
self.buffer_error(err);
|
self.buffer_error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -483,7 +474,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||||||
self.cannot_move_out_of_interior_noncopy(span, ty, None)
|
self.cannot_move_out_of_interior_noncopy(span, ty, None)
|
||||||
}
|
}
|
||||||
ty::Closure(def_id, closure_args)
|
ty::Closure(def_id, closure_args)
|
||||||
if def_id.as_local() == Some(self.mir_def_id()) && upvar_field.is_some() =>
|
if def_id.as_local() == Some(self.mir_def_id())
|
||||||
|
&& let Some(upvar_field) = upvar_field =>
|
||||||
{
|
{
|
||||||
let closure_kind_ty = closure_args.as_closure().kind_ty();
|
let closure_kind_ty = closure_args.as_closure().kind_ty();
|
||||||
let closure_kind = match closure_kind_ty.to_opt_closure_kind() {
|
let closure_kind = match closure_kind_ty.to_opt_closure_kind() {
|
||||||
@@ -496,7 +488,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||||||
let capture_description =
|
let capture_description =
|
||||||
format!("captured variable in an `{closure_kind}` closure");
|
format!("captured variable in an `{closure_kind}` closure");
|
||||||
|
|
||||||
let upvar = &self.upvars[upvar_field.unwrap().index()];
|
let upvar = &self.upvars[upvar_field.index()];
|
||||||
let upvar_hir_id = upvar.get_root_variable();
|
let upvar_hir_id = upvar.get_root_variable();
|
||||||
let upvar_name = upvar.to_string(tcx);
|
let upvar_name = upvar.to_string(tcx);
|
||||||
let upvar_span = tcx.hir_span(upvar_hir_id);
|
let upvar_span = tcx.hir_span(upvar_hir_id);
|
||||||
@@ -606,7 +598,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
// No binding. Nothing to suggest.
|
// No binding. Nothing to suggest.
|
||||||
GroupedMoveError::OtherIllegalMove { ref original_path, use_spans, .. } => {
|
GroupedMoveError::OtherIllegalMove { ref original_path, use_spans, .. } => {
|
||||||
let use_span = use_spans.var_or_use();
|
let mut use_span = use_spans.var_or_use();
|
||||||
let place_ty = original_path.ty(self.body, self.infcx.tcx).ty;
|
let place_ty = original_path.ty(self.body, self.infcx.tcx).ty;
|
||||||
let place_desc = match self.describe_place(original_path.as_ref()) {
|
let place_desc = match self.describe_place(original_path.as_ref()) {
|
||||||
Some(desc) => format!("`{desc}`"),
|
Some(desc) => format!("`{desc}`"),
|
||||||
@@ -623,6 +615,36 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(upvar_field) = self
|
||||||
|
.prefixes(original_path.as_ref(), PrefixSet::All)
|
||||||
|
.find_map(|p| self.is_upvar_field_projection(p))
|
||||||
|
{
|
||||||
|
// Look for the introduction of the original binding being moved.
|
||||||
|
let upvar = &self.upvars[upvar_field.index()];
|
||||||
|
let upvar_hir_id = upvar.get_root_variable();
|
||||||
|
use_span = match self.infcx.tcx.parent_hir_node(upvar_hir_id) {
|
||||||
|
hir::Node::Param(param) => {
|
||||||
|
// Instead of pointing at the path where we access the value within a
|
||||||
|
// closure, we point at the type of the outer `fn` argument.
|
||||||
|
param.ty_span
|
||||||
|
}
|
||||||
|
hir::Node::LetStmt(stmt) => match (stmt.ty, stmt.init) {
|
||||||
|
// We point at the type of the outer let-binding.
|
||||||
|
(Some(ty), _) => ty.span,
|
||||||
|
// We point at the initializer of the outer let-binding, but only if it
|
||||||
|
// isn't something that spans multiple lines, like a closure, as the
|
||||||
|
// ASCII art gets messy.
|
||||||
|
(None, Some(init))
|
||||||
|
if !self.infcx.tcx.sess.source_map().is_multiline(init.span) =>
|
||||||
|
{
|
||||||
|
init.span
|
||||||
|
}
|
||||||
|
_ => use_span,
|
||||||
|
},
|
||||||
|
_ => use_span,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
|
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
|
||||||
is_partial_move: false,
|
is_partial_move: false,
|
||||||
ty: place_ty,
|
ty: place_ty,
|
||||||
@@ -630,12 +652,22 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||||||
span: use_span,
|
span: use_span,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let mut pointed_at_span = false;
|
||||||
use_spans.args_subdiag(err, |args_span| {
|
use_spans.args_subdiag(err, |args_span| {
|
||||||
|
if args_span == span || args_span == use_span {
|
||||||
|
pointed_at_span = true;
|
||||||
|
}
|
||||||
crate::session_diagnostics::CaptureArgLabel::MoveOutPlace {
|
crate::session_diagnostics::CaptureArgLabel::MoveOutPlace {
|
||||||
place: place_desc,
|
place: place_desc.clone(),
|
||||||
args_span,
|
args_span,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if !pointed_at_span && use_span != span {
|
||||||
|
err.subdiagnostic(crate::session_diagnostics::CaptureArgLabel::MoveOutPlace {
|
||||||
|
place: place_desc,
|
||||||
|
args_span: span,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
self.add_note_for_packed_struct_derive(err, original_path.local);
|
self.add_note_for_packed_struct_derive(err, original_path.local);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
error[E0507]: cannot move out of `x` which is behind a mutable reference
|
error[E0507]: cannot move out of `x` which is behind a mutable reference
|
||||||
--> $DIR/closure-shim-borrowck-error.rs:11:18
|
--> $DIR/closure-shim-borrowck-error.rs:11:18
|
||||||
|
|
|
|
||||||
|
LL | fn hello(x: Ty) {
|
||||||
|
| -- move occurs because `x` has type `Ty`, which does not implement the `Copy` trait
|
||||||
LL | needs_fn_mut(async || {
|
LL | needs_fn_mut(async || {
|
||||||
| ^^^^^^^^ `x` is moved here
|
| ^^^^^^^^ `x` is moved here
|
||||||
LL |
|
LL |
|
||||||
LL | x.hello();
|
LL | x.hello();
|
||||||
| -
|
| - variable moved due to use in coroutine
|
||||||
| |
|
|
||||||
| variable moved due to use in coroutine
|
|
||||||
| move occurs because `x` has type `Ty`, which does not implement the `Copy` trait
|
|
||||||
|
|
|
|
||||||
note: if `Ty` implemented `Clone`, you could clone the value
|
note: if `Ty` implemented `Clone`, you could clone the value
|
||||||
--> $DIR/closure-shim-borrowck-error.rs:17:1
|
--> $DIR/closure-shim-borrowck-error.rs:17:1
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
error[E0507]: cannot move out of `*x` which is behind a shared reference
|
error[E0507]: cannot move out of `*x` which is behind a shared reference
|
||||||
--> $DIR/move-out-of-ref.rs:9:9
|
--> $DIR/move-out-of-ref.rs:9:9
|
||||||
|
|
|
|
||||||
|
LL | fn hello(x: &Ty) {
|
||||||
|
| --- move occurs because `*x` has type `Ty`, which does not implement the `Copy` trait
|
||||||
|
LL | let c = async || {
|
||||||
LL | *x;
|
LL | *x;
|
||||||
| ^^ move occurs because `*x` has type `Ty`, which does not implement the `Copy` trait
|
| ^^ `*x` is moved here
|
||||||
|
|
|
|
||||||
note: if `Ty` implemented `Clone`, you could clone the value
|
note: if `Ty` implemented `Clone`, you could clone the value
|
||||||
--> $DIR/move-out-of-ref.rs:5:1
|
--> $DIR/move-out-of-ref.rs:5:1
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
|
|||||||
--> $DIR/borrowck-in-static.rs:5:17
|
--> $DIR/borrowck-in-static.rs:5:17
|
||||||
|
|
|
|
||||||
LL | let x = Box::new(0);
|
LL | let x = Box::new(0);
|
||||||
| - captured outer variable
|
| - ----------- move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
|
||||||
|
| |
|
||||||
|
| captured outer variable
|
||||||
LL | Box::new(|| x)
|
LL | Box::new(|| x)
|
||||||
| -- ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
|
| -- ^ `x` is moved here
|
||||||
| |
|
| |
|
||||||
| captured by this `Fn` closure
|
| captured by this `Fn` closure
|
||||||
|
|
|
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ error[E0507]: cannot move out of `bar`, a captured variable in an `FnMut` closur
|
|||||||
--> $DIR/borrowck-move-by-capture.rs:9:29
|
--> $DIR/borrowck-move-by-capture.rs:9:29
|
||||||
|
|
|
|
||||||
LL | let bar: Box<_> = Box::new(3);
|
LL | let bar: Box<_> = Box::new(3);
|
||||||
| --- captured outer variable
|
| --- ------ move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
|
||||||
|
| |
|
||||||
|
| captured outer variable
|
||||||
LL | let _g = to_fn_mut(|| {
|
LL | let _g = to_fn_mut(|| {
|
||||||
| -- captured by this `FnMut` closure
|
| -- captured by this `FnMut` closure
|
||||||
LL | let _h = to_fn_once(move || -> isize { *bar });
|
LL | let _h = to_fn_once(move || -> isize { *bar });
|
||||||
| ^^^^^^^^^^^^^^^^ ----
|
| ^^^^^^^^^^^^^^^^ ---- variable moved due to use in closure
|
||||||
| | |
|
| |
|
||||||
| | variable moved due to use in closure
|
|
||||||
| | move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
|
|
||||||
| `bar` is moved here
|
| `bar` is moved here
|
||||||
|
|
|
|
||||||
help: consider cloning the value before moving it into the closure
|
help: consider cloning the value before moving it into the closure
|
||||||
|
|||||||
@@ -2,13 +2,16 @@ error[E0507]: cannot move out of `self.b`, as `self` is a captured variable in a
|
|||||||
--> $DIR/issue-103624.rs:16:13
|
--> $DIR/issue-103624.rs:16:13
|
||||||
|
|
|
|
||||||
LL | async fn foo(&self) {
|
LL | async fn foo(&self) {
|
||||||
| ----- captured outer variable
|
| -----
|
||||||
|
| |
|
||||||
|
| captured outer variable
|
||||||
|
| move occurs because `self.b` has type `StructB`, which does not implement the `Copy` trait
|
||||||
LL | let bar = self.b.bar().await;
|
LL | let bar = self.b.bar().await;
|
||||||
LL | spawn_blocking(move || {
|
LL | spawn_blocking(move || {
|
||||||
| ------- captured by this `Fn` closure
|
| ------- captured by this `Fn` closure
|
||||||
LL |
|
LL |
|
||||||
LL | self.b;
|
LL | self.b;
|
||||||
| ^^^^^^ move occurs because `self.b` has type `StructB`, which does not implement the `Copy` trait
|
| ^^^^^^ `self.b` is moved here
|
||||||
|
|
|
|
||||||
note: if `StructB` implemented `Clone`, you could clone the value
|
note: if `StructB` implemented `Clone`, you could clone the value
|
||||||
--> $DIR/issue-103624.rs:23:1
|
--> $DIR/issue-103624.rs:23:1
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ error[E0507]: cannot move out of `*v`, as `v` is a captured variable in an `FnMu
|
|||||||
--> $DIR/issue-4335.rs:6:20
|
--> $DIR/issue-4335.rs:6:20
|
||||||
|
|
|
|
||||||
LL | fn f<'r, T>(v: &'r T) -> Box<dyn FnMut() -> T + 'r> {
|
LL | fn f<'r, T>(v: &'r T) -> Box<dyn FnMut() -> T + 'r> {
|
||||||
| - captured outer variable
|
| - ----- move occurs because `*v` has type `T`, which does not implement the `Copy` trait
|
||||||
|
| |
|
||||||
|
| captured outer variable
|
||||||
LL | id(Box::new(|| *v))
|
LL | id(Box::new(|| *v))
|
||||||
| -- ^^ move occurs because `*v` has type `T`, which does not implement the `Copy` trait
|
| -- ^^ `*v` is moved here
|
||||||
| |
|
| |
|
||||||
| captured by this `FnMut` closure
|
| captured by this `FnMut` closure
|
||||||
|
|
|
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ error[E0507]: cannot move out of `i`, a captured variable in an `Fn` closure
|
|||||||
--> $DIR/moves-based-on-type-move-out-of-closure-env-issue-1965.rs:9:28
|
--> $DIR/moves-based-on-type-move-out-of-closure-env-issue-1965.rs:9:28
|
||||||
|
|
|
|
||||||
LL | let i = Box::new(3);
|
LL | let i = Box::new(3);
|
||||||
| - captured outer variable
|
| - ----------- move occurs because `i` has type `Box<usize>`, which does not implement the `Copy` trait
|
||||||
|
| |
|
||||||
|
| captured outer variable
|
||||||
LL | let _f = to_fn(|| test(i));
|
LL | let _f = to_fn(|| test(i));
|
||||||
| -- ^ move occurs because `i` has type `Box<usize>`, which does not implement the `Copy` trait
|
| -- ^ `i` is moved here
|
||||||
| |
|
| |
|
||||||
| captured by this `Fn` closure
|
| captured by this `Fn` closure
|
||||||
|
|
|
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn`
|
|||||||
--> $DIR/issue-52663-span-decl-captured-variable.rs:8:26
|
--> $DIR/issue-52663-span-decl-captured-variable.rs:8:26
|
||||||
|
|
|
|
||||||
LL | let x = (vec![22], vec![44]);
|
LL | let x = (vec![22], vec![44]);
|
||||||
| - captured outer variable
|
| - -------------------- move occurs because `x.0` has type `Vec<i32>`, which does not implement the `Copy` trait
|
||||||
|
| |
|
||||||
|
| captured outer variable
|
||||||
LL | expect_fn(|| drop(x.0));
|
LL | expect_fn(|| drop(x.0));
|
||||||
| -- ^^^ move occurs because `x.0` has type `Vec<i32>`, which does not implement the `Copy` trait
|
| -- ^^^ `x.0` is moved here
|
||||||
| |
|
| |
|
||||||
| captured by this `Fn` closure
|
| captured by this `Fn` closure
|
||||||
|
|
|
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closur
|
|||||||
--> $DIR/option-content-move2.rs:11:9
|
--> $DIR/option-content-move2.rs:11:9
|
||||||
|
|
|
|
||||||
LL | let mut var = None;
|
LL | let mut var = None;
|
||||||
| ------- captured outer variable
|
| ------- ---- move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
|
||||||
|
| |
|
||||||
|
| captured outer variable
|
||||||
LL | func(|| {
|
LL | func(|| {
|
||||||
| -- captured by this `FnMut` closure
|
| -- captured by this `FnMut` closure
|
||||||
LL | // Shouldn't suggest `move ||.as_ref()` here
|
LL | // Shouldn't suggest `move ||.as_ref()` here
|
||||||
@@ -10,16 +12,15 @@ LL | move || {
|
|||||||
| ^^^^^^^ `var` is moved here
|
| ^^^^^^^ `var` is moved here
|
||||||
LL |
|
LL |
|
||||||
LL | var = Some(NotCopyable);
|
LL | var = Some(NotCopyable);
|
||||||
| ---
|
| --- variable moved due to use in closure
|
||||||
| |
|
|
||||||
| variable moved due to use in closure
|
|
||||||
| move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
|
|
||||||
|
|
||||||
error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
|
error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
|
||||||
--> $DIR/option-content-move2.rs:21:9
|
--> $DIR/option-content-move2.rs:21:9
|
||||||
|
|
|
|
||||||
LL | let mut var = None;
|
LL | let mut var = None;
|
||||||
| ------- captured outer variable
|
| ------- ---- move occurs because `var` has type `Option<NotCopyableButCloneable>`, which does not implement the `Copy` trait
|
||||||
|
| |
|
||||||
|
| captured outer variable
|
||||||
LL | func(|| {
|
LL | func(|| {
|
||||||
| -- captured by this `FnMut` closure
|
| -- captured by this `FnMut` closure
|
||||||
LL | // Shouldn't suggest `move ||.as_ref()` nor to `clone()` here
|
LL | // Shouldn't suggest `move ||.as_ref()` nor to `clone()` here
|
||||||
@@ -27,10 +28,7 @@ LL | move || {
|
|||||||
| ^^^^^^^ `var` is moved here
|
| ^^^^^^^ `var` is moved here
|
||||||
LL |
|
LL |
|
||||||
LL | var = Some(NotCopyableButCloneable);
|
LL | var = Some(NotCopyableButCloneable);
|
||||||
| ---
|
| --- variable moved due to use in closure
|
||||||
| |
|
|
||||||
| variable moved due to use in closure
|
|
||||||
| move occurs because `var` has type `Option<NotCopyableButCloneable>`, which does not implement the `Copy` trait
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|||||||
@@ -26,17 +26,16 @@ error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closur
|
|||||||
--> $DIR/option-content-move3.rs:12:9
|
--> $DIR/option-content-move3.rs:12:9
|
||||||
|
|
|
|
||||||
LL | let var = NotCopyable;
|
LL | let var = NotCopyable;
|
||||||
| --- captured outer variable
|
| --- ----------- move occurs because `var` has type `NotCopyable`, which does not implement the `Copy` trait
|
||||||
|
| |
|
||||||
|
| captured outer variable
|
||||||
LL | func(|| {
|
LL | func(|| {
|
||||||
| -- captured by this `FnMut` closure
|
| -- captured by this `FnMut` closure
|
||||||
LL | // Shouldn't suggest `move ||.as_ref()` here
|
LL | // Shouldn't suggest `move ||.as_ref()` here
|
||||||
LL | move || {
|
LL | move || {
|
||||||
| ^^^^^^^ `var` is moved here
|
| ^^^^^^^ `var` is moved here
|
||||||
LL | let x = var;
|
LL | let x = var;
|
||||||
| ---
|
| --- variable moved due to use in closure
|
||||||
| |
|
|
||||||
| variable moved due to use in closure
|
|
||||||
| move occurs because `var` has type `NotCopyable`, which does not implement the `Copy` trait
|
|
||||||
|
|
|
|
||||||
note: if `NotCopyable` implemented `Clone`, you could clone the value
|
note: if `NotCopyable` implemented `Clone`, you could clone the value
|
||||||
--> $DIR/option-content-move3.rs:2:1
|
--> $DIR/option-content-move3.rs:2:1
|
||||||
@@ -67,17 +66,16 @@ error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closur
|
|||||||
--> $DIR/option-content-move3.rs:23:9
|
--> $DIR/option-content-move3.rs:23:9
|
||||||
|
|
|
|
||||||
LL | let var = NotCopyableButCloneable;
|
LL | let var = NotCopyableButCloneable;
|
||||||
| --- captured outer variable
|
| --- ----------------------- move occurs because `var` has type `NotCopyableButCloneable`, which does not implement the `Copy` trait
|
||||||
|
| |
|
||||||
|
| captured outer variable
|
||||||
LL | func(|| {
|
LL | func(|| {
|
||||||
| -- captured by this `FnMut` closure
|
| -- captured by this `FnMut` closure
|
||||||
LL | // Shouldn't suggest `move ||.as_ref()` here
|
LL | // Shouldn't suggest `move ||.as_ref()` here
|
||||||
LL | move || {
|
LL | move || {
|
||||||
| ^^^^^^^ `var` is moved here
|
| ^^^^^^^ `var` is moved here
|
||||||
LL | let x = var;
|
LL | let x = var;
|
||||||
| ---
|
| --- variable moved due to use in closure
|
||||||
| |
|
|
||||||
| variable moved due to use in closure
|
|
||||||
| move occurs because `var` has type `NotCopyableButCloneable`, which does not implement the `Copy` trait
|
|
||||||
|
|
|
|
||||||
help: consider cloning the value before moving it into the closure
|
help: consider cloning the value before moving it into the closure
|
||||||
|
|
|
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
|
|||||||
--> $DIR/unboxed-closure-illegal-move.rs:15:31
|
--> $DIR/unboxed-closure-illegal-move.rs:15:31
|
||||||
|
|
|
|
||||||
LL | let x = Box::new(0);
|
LL | let x = Box::new(0);
|
||||||
| - captured outer variable
|
| - ----------- move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
|
||||||
|
| |
|
||||||
|
| captured outer variable
|
||||||
LL | let f = to_fn(|| drop(x));
|
LL | let f = to_fn(|| drop(x));
|
||||||
| -- ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
|
| -- ^ `x` is moved here
|
||||||
| |
|
| |
|
||||||
| captured by this `Fn` closure
|
| captured by this `Fn` closure
|
||||||
|
|
|
|
||||||
@@ -17,9 +19,11 @@ error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
|
|||||||
--> $DIR/unboxed-closure-illegal-move.rs:19:35
|
--> $DIR/unboxed-closure-illegal-move.rs:19:35
|
||||||
|
|
|
|
||||||
LL | let x = Box::new(0);
|
LL | let x = Box::new(0);
|
||||||
| - captured outer variable
|
| - ----------- move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
|
||||||
|
| |
|
||||||
|
| captured outer variable
|
||||||
LL | let f = to_fn_mut(|| drop(x));
|
LL | let f = to_fn_mut(|| drop(x));
|
||||||
| -- ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
|
| -- ^ `x` is moved here
|
||||||
| |
|
| |
|
||||||
| captured by this `FnMut` closure
|
| captured by this `FnMut` closure
|
||||||
|
|
|
|
||||||
@@ -32,9 +36,11 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
|
|||||||
--> $DIR/unboxed-closure-illegal-move.rs:28:36
|
--> $DIR/unboxed-closure-illegal-move.rs:28:36
|
||||||
|
|
|
|
||||||
LL | let x = Box::new(0);
|
LL | let x = Box::new(0);
|
||||||
| - captured outer variable
|
| - ----------- move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
|
||||||
|
| |
|
||||||
|
| captured outer variable
|
||||||
LL | let f = to_fn(move || drop(x));
|
LL | let f = to_fn(move || drop(x));
|
||||||
| ------- ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
|
| ------- ^ `x` is moved here
|
||||||
| |
|
| |
|
||||||
| captured by this `Fn` closure
|
| captured by this `Fn` closure
|
||||||
|
|
||||||
@@ -42,9 +48,11 @@ error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
|
|||||||
--> $DIR/unboxed-closure-illegal-move.rs:32:40
|
--> $DIR/unboxed-closure-illegal-move.rs:32:40
|
||||||
|
|
|
|
||||||
LL | let x = Box::new(0);
|
LL | let x = Box::new(0);
|
||||||
| - captured outer variable
|
| - ----------- move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
|
||||||
|
| |
|
||||||
|
| captured outer variable
|
||||||
LL | let f = to_fn_mut(move || drop(x));
|
LL | let f = to_fn_mut(move || drop(x));
|
||||||
| ------- ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
|
| ------- ^ `x` is moved here
|
||||||
| |
|
| |
|
||||||
| captured by this `FnMut` closure
|
| captured by this `FnMut` closure
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user