1
Fork 0

Point to closure when emitting 'cannot move out' for captured variable

This commit is contained in:
Fabian Wolff 2021-07-25 20:05:41 +02:00
parent c3c0f80d60
commit 21b7052eb8
13 changed files with 503 additions and 215 deletions

View file

@ -336,15 +336,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if def_id.as_local() == Some(self.mir_def_id()) && upvar_field.is_some() => if def_id.as_local() == Some(self.mir_def_id()) && upvar_field.is_some() =>
{ {
let closure_kind_ty = closure_substs.as_closure().kind_ty(); let closure_kind_ty = closure_substs.as_closure().kind_ty();
let closure_kind = closure_kind_ty.to_opt_closure_kind(); let closure_kind = match closure_kind_ty.to_opt_closure_kind() {
let capture_description = match closure_kind { Some(kind @ (ty::ClosureKind::Fn | ty::ClosureKind::FnMut)) => kind,
Some(ty::ClosureKind::Fn) => "captured variable in an `Fn` closure",
Some(ty::ClosureKind::FnMut) => "captured variable in an `FnMut` closure",
Some(ty::ClosureKind::FnOnce) => { Some(ty::ClosureKind::FnOnce) => {
bug!("closure kind does not match first argument type") bug!("closure kind does not match first argument type")
} }
None => bug!("closure kind not inferred by borrowck"), None => bug!("closure kind not inferred by borrowck"),
}; };
let capture_description =
format!("captured variable in an `{}` closure", closure_kind);
let upvar = &self.upvars[upvar_field.unwrap().index()]; let upvar = &self.upvars[upvar_field.unwrap().index()];
let upvar_hir_id = upvar.place.get_root_variable(); let upvar_hir_id = upvar.place.get_root_variable();
@ -368,6 +368,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let mut diag = self.cannot_move_out_of(span, &place_description); let mut diag = self.cannot_move_out_of(span, &place_description);
diag.span_label(upvar_span, "captured outer variable"); diag.span_label(upvar_span, "captured outer variable");
diag.span_label(
self.body.span,
format!("captured by this `{}` closure", closure_kind),
);
diag diag
} }

View file

@ -4,7 +4,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
LL | let x = Box::new(0); LL | let x = Box::new(0);
| - captured outer variable | - 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 | ---^
| | |
| | move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
| captured by this `Fn` closure
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,15 +1,18 @@
error[E0507]: cannot move out of `bar`, a captured variable in an `FnMut` closure error[E0507]: cannot move out of `bar`, a captured variable in an `FnMut` closure
--> $DIR/borrowck-move-by-capture.rs:9:29 --> $DIR/borrowck-move-by-capture.rs:9:29
| |
LL | let bar: Box<_> = box 3; LL | let bar: Box<_> = box 3;
| --- captured outer variable | --- captured outer variable
LL | let _g = to_fn_mut(|| { LL | let _g = to_fn_mut(|| {
LL | let _h = to_fn_once(move || -> isize { *bar }); | ________________________-
| ^^^^^^^^^^^^^^^^ ---- LL | | let _h = to_fn_once(move || -> isize { *bar });
| | | | | ^^^^^^^^^^^^^^^^ ----
| | move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait | | | |
| | move occurs due to use in closure | | | move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
| move out of `bar` occurs here | | | move occurs due to use in closure
| | move out of `bar` occurs here
LL | | });
| |_____- captured by this `FnMut` closure
error: aborting due to previous error error: aborting due to previous error

View file

@ -0,0 +1,14 @@
// Regression test for #87456.
fn take_mut(_val: impl FnMut()) {}
fn main() {
let val = String::new();
//~^ NOTE: captured outer variable
take_mut(|| {
//~^ NOTE: captured by this `FnMut` closure
let _foo: String = val;
//~^ ERROR: cannot move out of `val`, a captured variable in an `FnMut` closure [E0507]
//~| NOTE: move occurs because
})
}

View file

@ -0,0 +1,22 @@
error[E0507]: cannot move out of `val`, a captured variable in an `FnMut` closure
--> $DIR/issue-87456-point-to-closure.rs:10:28
|
LL | let val = String::new();
| --- captured outer variable
LL |
LL | take_mut(|| {
| ______________-
LL | |
LL | | let _foo: String = val;
| | ^^^
| | |
| | move occurs because `val` has type `String`, which does not implement the `Copy` trait
| | help: consider borrowing here: `&val`
LL | |
LL | |
LL | | })
| |_____- captured by this `FnMut` closure
error: aborting due to previous error
For more information about this error, try `rustc --explain E0507`.

View file

@ -1,11 +1,15 @@
error[E0507]: cannot move out of `y`, a captured variable in an `Fn` closure error[E0507]: cannot move out of `y`, a captured variable in an `Fn` closure
--> $DIR/unboxed-closures-move-upvar-from-non-once-ref-closure.rs:11:9 --> $DIR/unboxed-closures-move-upvar-from-non-once-ref-closure.rs:11:9
| |
LL | let y = vec![format!("World")]; LL | let y = vec![format!("World")];
| - captured outer variable | - captured outer variable
LL | call(|| { LL | call(|| {
LL | y.into_iter(); | __________-
| ^ move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait LL | | y.into_iter();
| | ^ move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait
LL | |
LL | | });
| |_____- captured by this `Fn` closure
error: aborting due to previous error error: aborting due to previous error

View file

@ -4,7 +4,10 @@ error[E0507]: cannot move out of `*v`, as `v` is a captured variable in an `FnMu
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 | - 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 | ---^^
| | |
| | move occurs because `*v` has type `T`, which does not implement the `Copy` trait
| captured by this `FnMut` closure
error: aborting due to previous error error: aborting due to previous error

View file

@ -4,7 +4,10 @@ error[E0507]: cannot move out of `i`, a captured variable in an `Fn` closure
LL | let i = box 3; LL | let i = box 3;
| - captured outer variable | - 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 | --------^-
| | |
| | move occurs because `i` has type `Box<usize>`, which does not implement the `Copy` trait
| captured by this `Fn` closure
error: aborting due to previous error error: aborting due to previous error

View file

@ -4,7 +4,10 @@ error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn`
LL | let x = (vec![22], vec![44]); LL | let x = (vec![22], vec![44]);
| - captured outer variable | - 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 | --------^^^-
| | |
| | move occurs because `x.0` has type `Vec<i32>`, which does not implement the `Copy` trait
| captured by this `Fn` closure
error: aborting due to previous error error: aborting due to previous error

View file

@ -29,11 +29,17 @@ LL | f.f.call_mut(())
error[E0507]: cannot move out of `f`, a captured variable in an `FnMut` closure error[E0507]: cannot move out of `f`, a captured variable in an `FnMut` closure
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:57:13 --> $DIR/borrowck-call-is-borrow-issue-12224.rs:57:13
| |
LL | let mut f = move |g: Box<dyn FnMut(isize)>, b: isize| { LL | let mut f = move |g: Box<dyn FnMut(isize)>, b: isize| {
| ----- captured outer variable | ----- captured outer variable
... ...
LL | foo(f); LL | f(Box::new(|a| {
| ^ move occurs because `f` has type `[closure@$DIR/borrowck-call-is-borrow-issue-12224.rs:52:17: 54:6]`, which does not implement the `Copy` trait | ________________-
LL | |
LL | | foo(f);
| | ^ move occurs because `f` has type `[closure@$DIR/borrowck-call-is-borrow-issue-12224.rs:52:17: 54:6]`, which does not implement the `Copy` trait
LL | |
LL | | }), 3);
| |_____- captured by this `FnMut` closure
error[E0505]: cannot move out of `f` because it is borrowed error[E0505]: cannot move out of `f` because it is borrowed
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:55:16 --> $DIR/borrowck-call-is-borrow-issue-12224.rs:55:16

View file

@ -1,281 +1,487 @@
error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure
--> $DIR/move-into-closure.rs:28:21 --> $DIR/move-into-closure.rs:28:21
| |
LL | let x = X(Y); LL | let x = X(Y);
| - captured outer variable | - captured outer variable
... ...
LL | let X(_t) = x; LL | consume_fn(|| {
| -- ^ help: consider borrowing here: `&x` | ________________-
| | LL | | let X(_t) = x;
| data moved here | | -- ^ help: consider borrowing here: `&x`
| move occurs because `_t` has type `Y`, which does not implement the `Copy` trait | | |
| | data moved here
| | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
LL | |
LL | |
... |
LL | | }
LL | | });
| |_____- captured by this `Fn` closure
error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure
--> $DIR/move-into-closure.rs:32:34 --> $DIR/move-into-closure.rs:32:34
| |
LL | let e = Either::One(X(Y)); LL | let e = Either::One(X(Y));
| - captured outer variable | - captured outer variable
... ...
LL | if let Either::One(_t) = e { } LL | consume_fn(|| {
| -- ^ help: consider borrowing here: `&e` | ________________-
| | LL | | let X(_t) = x;
| data moved here LL | |
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait LL | |
LL | |
LL | | if let Either::One(_t) = e { }
| | -- ^ help: consider borrowing here: `&e`
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `Fn` closure
error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure
--> $DIR/move-into-closure.rs:36:37 --> $DIR/move-into-closure.rs:36:37
| |
LL | let e = Either::One(X(Y)); LL | let e = Either::One(X(Y));
| - captured outer variable | - captured outer variable
... ...
LL | while let Either::One(_t) = e { } LL | consume_fn(|| {
| -- ^ help: consider borrowing here: `&e` | ________________-
| | LL | | let X(_t) = x;
| data moved here LL | |
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait LL | |
... |
LL | | while let Either::One(_t) = e { }
| | -- ^ help: consider borrowing here: `&e`
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `Fn` closure
error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure
--> $DIR/move-into-closure.rs:40:15 --> $DIR/move-into-closure.rs:40:15
| |
LL | let e = Either::One(X(Y)); LL | let e = Either::One(X(Y));
| - captured outer variable | - captured outer variable
... ...
LL | match e { LL | consume_fn(|| {
| ^ help: consider borrowing here: `&e` | ________________-
... LL | | let X(_t) = x;
LL | Either::One(_t) LL | |
| -- LL | |
| | ... |
| data moved here LL | | match e {
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait | | ^ help: consider borrowing here: `&e`
... |
LL | | Either::One(_t)
| | --
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `Fn` closure
error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure
--> $DIR/move-into-closure.rs:47:15 --> $DIR/move-into-closure.rs:47:15
| |
LL | let e = Either::One(X(Y)); LL | let e = Either::One(X(Y));
| - captured outer variable | - captured outer variable
... ...
LL | match e { LL | consume_fn(|| {
| ^ help: consider borrowing here: `&e` | ________________-
... LL | | let X(_t) = x;
LL | Either::One(_t) => (), LL | |
| -- LL | |
| | ... |
| data moved here LL | | match e {
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait | | ^ help: consider borrowing here: `&e`
... |
LL | | Either::One(_t) => (),
| | --
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `Fn` closure
error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure
--> $DIR/move-into-closure.rs:56:25 --> $DIR/move-into-closure.rs:56:25
| |
LL | let x = X(Y); LL | let x = X(Y);
| - captured outer variable | - captured outer variable
... ...
LL | let X(mut _t) = x; LL | consume_fn(|| {
| ------ ^ help: consider borrowing here: `&x` | ________________-
| | LL | | let X(_t) = x;
| data moved here LL | |
| move occurs because `_t` has type `Y`, which does not implement the `Copy` trait LL | |
... |
LL | | let X(mut _t) = x;
| | ------ ^ help: consider borrowing here: `&x`
| | |
| | data moved here
| | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `Fn` closure
error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure
--> $DIR/move-into-closure.rs:60:38 --> $DIR/move-into-closure.rs:60:38
| |
LL | let mut em = Either::One(X(Y)); LL | let mut em = Either::One(X(Y));
| ------ captured outer variable | ------ captured outer variable
... ...
LL | if let Either::One(mut _t) = em { } LL | consume_fn(|| {
| ------ ^^ help: consider borrowing here: `&em` | ________________-
| | LL | | let X(_t) = x;
| data moved here LL | |
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait LL | |
... |
LL | | if let Either::One(mut _t) = em { }
| | ------ ^^ help: consider borrowing here: `&em`
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `Fn` closure
error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure
--> $DIR/move-into-closure.rs:64:41 --> $DIR/move-into-closure.rs:64:41
| |
LL | let mut em = Either::One(X(Y)); LL | let mut em = Either::One(X(Y));
| ------ captured outer variable | ------ captured outer variable
... ...
LL | while let Either::One(mut _t) = em { } LL | consume_fn(|| {
| ------ ^^ help: consider borrowing here: `&em` | ________________-
| | LL | | let X(_t) = x;
| data moved here LL | |
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait LL | |
... |
LL | | while let Either::One(mut _t) = em { }
| | ------ ^^ help: consider borrowing here: `&em`
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `Fn` closure
error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure
--> $DIR/move-into-closure.rs:68:15 --> $DIR/move-into-closure.rs:68:15
| |
LL | let mut em = Either::One(X(Y)); LL | let mut em = Either::One(X(Y));
| ------ captured outer variable | ------ captured outer variable
... ...
LL | match em { LL | consume_fn(|| {
| ^^ help: consider borrowing here: `&em` | ________________-
... LL | | let X(_t) = x;
LL | Either::One(mut _t) LL | |
| ------ LL | |
| | ... |
| data moved here LL | | match em {
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait | | ^^ help: consider borrowing here: `&em`
... |
LL | | Either::One(mut _t)
| | ------
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `Fn` closure
error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure
--> $DIR/move-into-closure.rs:75:15 --> $DIR/move-into-closure.rs:75:15
| |
LL | let mut em = Either::One(X(Y)); LL | let mut em = Either::One(X(Y));
| ------ captured outer variable | ------ captured outer variable
... ...
LL | match em { LL | consume_fn(|| {
| ^^ help: consider borrowing here: `&em` | ________________-
... LL | | let X(_t) = x;
LL | Either::One(mut _t) => (), LL | |
| ------ LL | |
| | ... |
| data moved here LL | | match em {
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait | | ^^ help: consider borrowing here: `&em`
... |
LL | | Either::One(mut _t) => (),
| | ------
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `Fn` closure
error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `FnMut` closure error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `FnMut` closure
--> $DIR/move-into-closure.rs:95:21 --> $DIR/move-into-closure.rs:95:21
| |
LL | let x = X(Y); LL | let x = X(Y);
| - captured outer variable | - captured outer variable
... ...
LL | let X(_t) = x; LL | consume_fnmut(|| {
| -- ^ help: consider borrowing here: `&x` | ___________________-
| | LL | | let X(_t) = x;
| data moved here | | -- ^ help: consider borrowing here: `&x`
| move occurs because `_t` has type `Y`, which does not implement the `Copy` trait | | |
| | data moved here
| | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
LL | |
LL | |
... |
LL | | }
LL | | });
| |_____- captured by this `FnMut` closure
error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure
--> $DIR/move-into-closure.rs:99:34 --> $DIR/move-into-closure.rs:99:34
| |
LL | let e = Either::One(X(Y)); LL | let e = Either::One(X(Y));
| - captured outer variable | - captured outer variable
... ...
LL | if let Either::One(_t) = e { } LL | consume_fnmut(|| {
| -- ^ help: consider borrowing here: `&e` | ___________________-
| | LL | | let X(_t) = x;
| data moved here LL | |
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait LL | |
LL | |
LL | | if let Either::One(_t) = e { }
| | -- ^ help: consider borrowing here: `&e`
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `FnMut` closure
error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure
--> $DIR/move-into-closure.rs:103:37 --> $DIR/move-into-closure.rs:103:37
| |
LL | let e = Either::One(X(Y)); LL | let e = Either::One(X(Y));
| - captured outer variable | - captured outer variable
... ...
LL | while let Either::One(_t) = e { } LL | consume_fnmut(|| {
| -- ^ help: consider borrowing here: `&e` | ___________________-
| | LL | | let X(_t) = x;
| data moved here LL | |
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait LL | |
... |
LL | | while let Either::One(_t) = e { }
| | -- ^ help: consider borrowing here: `&e`
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `FnMut` closure
error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure
--> $DIR/move-into-closure.rs:107:15 --> $DIR/move-into-closure.rs:107:15
| |
LL | let e = Either::One(X(Y)); LL | let e = Either::One(X(Y));
| - captured outer variable | - captured outer variable
... ...
LL | match e { LL | consume_fnmut(|| {
| ^ help: consider borrowing here: `&e` | ___________________-
... LL | | let X(_t) = x;
LL | Either::One(_t) LL | |
| -- LL | |
| | ... |
| data moved here LL | | match e {
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait | | ^ help: consider borrowing here: `&e`
... |
LL | | Either::One(_t)
| | --
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `FnMut` closure
error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure
--> $DIR/move-into-closure.rs:114:15 --> $DIR/move-into-closure.rs:114:15
| |
LL | let e = Either::One(X(Y)); LL | let e = Either::One(X(Y));
| - captured outer variable | - captured outer variable
... ...
LL | match e { LL | consume_fnmut(|| {
| ^ help: consider borrowing here: `&e` | ___________________-
... LL | | let X(_t) = x;
LL | Either::One(_t) => (), LL | |
| -- LL | |
| | ... |
| data moved here LL | | match e {
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait | | ^ help: consider borrowing here: `&e`
... |
LL | | Either::One(_t) => (),
| | --
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `FnMut` closure
error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `FnMut` closure error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `FnMut` closure
--> $DIR/move-into-closure.rs:123:25 --> $DIR/move-into-closure.rs:123:25
| |
LL | let x = X(Y); LL | let x = X(Y);
| - captured outer variable | - captured outer variable
... ...
LL | let X(mut _t) = x; LL | consume_fnmut(|| {
| ------ ^ help: consider borrowing here: `&x` | ___________________-
| | LL | | let X(_t) = x;
| data moved here LL | |
| move occurs because `_t` has type `Y`, which does not implement the `Copy` trait LL | |
... |
LL | | let X(mut _t) = x;
| | ------ ^ help: consider borrowing here: `&x`
| | |
| | data moved here
| | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `FnMut` closure
error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
--> $DIR/move-into-closure.rs:127:38 --> $DIR/move-into-closure.rs:127:38
| |
LL | let mut em = Either::One(X(Y)); LL | let mut em = Either::One(X(Y));
| ------ captured outer variable | ------ captured outer variable
... ...
LL | if let Either::One(mut _t) = em { } LL | consume_fnmut(|| {
| ------ ^^ help: consider borrowing here: `&em` | ___________________-
| | LL | | let X(_t) = x;
| data moved here LL | |
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait LL | |
... |
LL | | if let Either::One(mut _t) = em { }
| | ------ ^^ help: consider borrowing here: `&em`
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `FnMut` closure
error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
--> $DIR/move-into-closure.rs:131:41 --> $DIR/move-into-closure.rs:131:41
| |
LL | let mut em = Either::One(X(Y)); LL | let mut em = Either::One(X(Y));
| ------ captured outer variable | ------ captured outer variable
... ...
LL | while let Either::One(mut _t) = em { } LL | consume_fnmut(|| {
| ------ ^^ help: consider borrowing here: `&em` | ___________________-
| | LL | | let X(_t) = x;
| data moved here LL | |
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait LL | |
... |
LL | | while let Either::One(mut _t) = em { }
| | ------ ^^ help: consider borrowing here: `&em`
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `FnMut` closure
error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
--> $DIR/move-into-closure.rs:135:15 --> $DIR/move-into-closure.rs:135:15
| |
LL | let mut em = Either::One(X(Y)); LL | let mut em = Either::One(X(Y));
| ------ captured outer variable | ------ captured outer variable
... ...
LL | match em { LL | consume_fnmut(|| {
| ^^ help: consider borrowing here: `&em` | ___________________-
... LL | | let X(_t) = x;
LL | Either::One(mut _t) LL | |
| ------ LL | |
| | ... |
| data moved here LL | | match em {
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait | | ^^ help: consider borrowing here: `&em`
... |
LL | | Either::One(mut _t)
| | ------
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `FnMut` closure
error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
--> $DIR/move-into-closure.rs:142:15 --> $DIR/move-into-closure.rs:142:15
| |
LL | let mut em = Either::One(X(Y)); LL | let mut em = Either::One(X(Y));
| ------ captured outer variable | ------ captured outer variable
... ...
LL | match em { LL | consume_fnmut(|| {
| ^^ help: consider borrowing here: `&em` | ___________________-
... LL | | let X(_t) = x;
LL | Either::One(mut _t) => (), LL | |
| ------ LL | |
| | ... |
| data moved here LL | | match em {
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait | | ^^ help: consider borrowing here: `&em`
... |
LL | | Either::One(mut _t) => (),
| | ------
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `FnMut` closure
error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
--> $DIR/move-into-closure.rs:150:15 --> $DIR/move-into-closure.rs:150:15
| |
LL | let mut em = Either::One(X(Y)); LL | let mut em = Either::One(X(Y));
| ------ captured outer variable | ------ captured outer variable
... ...
LL | match em { LL | consume_fnmut(|| {
| ^^ help: consider borrowing here: `&em` | ___________________-
... LL | | let X(_t) = x;
LL | Either::One(mut _t) => (), LL | |
| ------ LL | |
| | ... |
| data moved here LL | | match em {
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait | | ^^ help: consider borrowing here: `&em`
... |
LL | | Either::One(mut _t) => (),
| | ------
| | |
| | data moved here
| | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
... |
LL | | }
LL | | });
| |_____- captured by this `FnMut` closure
error: aborting due to 21 previous errors error: aborting due to 21 previous errors

View file

@ -1,17 +1,22 @@
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:9:9 --> $DIR/option-content-move2.rs:9:9
| |
LL | let mut var = None; LL | let mut var = None;
| ------- captured outer variable | ------- captured outer variable
... LL | func(|| {
LL | move || { | __________-
| ^^^^^^^ move out of `var` occurs here LL | | // Shouldn't suggest `move ||.as_ref()` here
LL | LL | | move || {
LL | var = Some(NotCopyable); | | ^^^^^^^ move out of `var` occurs here
| --- LL | |
| | LL | | var = Some(NotCopyable);
| move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait | | ---
| move occurs due to use in closure | | |
| | move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
| | move occurs due to use in closure
LL | | }
LL | | });
| |_____- captured by this `FnMut` closure
error: aborting due to previous error error: aborting due to previous error

View file

@ -4,7 +4,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
LL | let x = Box::new(0); LL | let x = Box::new(0);
| - captured outer variable | - 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 | --------^-
| | |
| | move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
| captured by this `Fn` closure
error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure 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
@ -12,7 +15,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
LL | let x = Box::new(0); LL | let x = Box::new(0);
| - captured outer variable | - 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 | --------^-
| | |
| | move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
| captured by this `FnMut` closure
error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure 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
@ -20,7 +26,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
LL | let x = Box::new(0); LL | let x = Box::new(0);
| - captured outer variable | - 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 | -------------^-
| | |
| | move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
| captured by this `Fn` closure
error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure 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
@ -28,7 +37,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
LL | let x = Box::new(0); LL | let x = Box::new(0);
| - captured outer variable | - 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 | -------------^-
| | |
| | move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
| captured by this `FnMut` closure
error: aborting due to 4 previous errors error: aborting due to 4 previous errors