Skip to content

Commit

Permalink
Point to closure when emitting 'cannot move out' for captured variable
Browse files Browse the repository at this point in the history
  • Loading branch information
FabianWolff committed Sep 14, 2021
1 parent c3c0f80 commit 21b7052
Show file tree
Hide file tree
Showing 13 changed files with 503 additions and 215 deletions.
12 changes: 8 additions & 4 deletions compiler/rustc_borrowck/src/diagnostics/move_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,15 +336,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
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 = closure_kind_ty.to_opt_closure_kind();
let capture_description = match closure_kind {
Some(ty::ClosureKind::Fn) => "captured variable in an `Fn` closure",
Some(ty::ClosureKind::FnMut) => "captured variable in an `FnMut` closure",
let closure_kind = match closure_kind_ty.to_opt_closure_kind() {
Some(kind @ (ty::ClosureKind::Fn | ty::ClosureKind::FnMut)) => kind,
Some(ty::ClosureKind::FnOnce) => {
bug!("closure kind does not match first argument type")
}
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_hir_id = upvar.place.get_root_variable();
Expand All @@ -368,6 +368,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let mut diag = self.cannot_move_out_of(span, &place_description);

diag.span_label(upvar_span, "captured outer variable");
diag.span_label(
self.body.span,
format!("captured by this `{}` closure", closure_kind),
);

diag
}
Expand Down
5 changes: 4 additions & 1 deletion src/test/ui/borrowck/borrowck-in-static.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
LL | let x = Box::new(0);
| - captured outer variable
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

Expand Down
21 changes: 12 additions & 9 deletions src/test/ui/borrowck/borrowck-move-by-capture.stderr
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
error[E0507]: cannot move out of `bar`, a captured variable in an `FnMut` closure
--> $DIR/borrowck-move-by-capture.rs:9:29
|
LL | let bar: Box<_> = box 3;
| --- captured outer variable
LL | let _g = to_fn_mut(|| {
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 out of `bar` occurs here
LL | let bar: Box<_> = box 3;
| --- captured outer variable
LL | let _g = to_fn_mut(|| {
| ________________________-
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 out of `bar` occurs here
LL | | });
| |_____- captured by this `FnMut` closure

error: aborting due to previous error

Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/borrowck/issue-87456-point-to-closure.rs
Original file line number Diff line number Diff line change
@@ -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
})
}
22 changes: 22 additions & 0 deletions src/test/ui/borrowck/issue-87456-point-to-closure.stderr
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
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
|
LL | let y = vec![format!("World")];
| - captured outer variable
LL | call(|| {
LL | y.into_iter();
| ^ move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait
LL | let y = vec![format!("World")];
| - captured outer variable
LL | call(|| {
| __________-
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

Expand Down
5 changes: 4 additions & 1 deletion src/test/ui/issues/issue-4335.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
| - captured outer variable
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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ error[E0507]: cannot move out of `i`, a captured variable in an `Fn` closure
LL | let i = box 3;
| - captured outer variable
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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
| - captured outer variable
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

Expand Down
14 changes: 10 additions & 4 deletions src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,17 @@ LL | f.f.call_mut(())
error[E0507]: cannot move out of `f`, a captured variable in an `FnMut` closure
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:57:13
|
LL | let mut f = move |g: Box<dyn FnMut(isize)>, b: isize| {
| ----- captured outer variable
LL | let mut f = move |g: Box<dyn FnMut(isize)>, b: isize| {
| ----- captured outer variable
...
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 | f(Box::new(|a| {
| ________________-
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
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:55:16
Expand Down
Loading

0 comments on commit 21b7052

Please sign in to comment.