about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2020-02-02 21:17:49 +0100
committerMazdak Farrokhzad <twingoow@gmail.com>2020-02-02 21:17:49 +0100
commitd2b88b7050b0e21b136022c4cfe8d352c1425588 (patch)
tree9f25bbf6188739bb31831707495839d4d067435c
parentbd318be05dab2e1149595aacbf3d808559fa42dc (diff)
move_ref_pattern: test captures inside closure
-rw-r--r--src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs122
-rw-r--r--src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.stderr404
2 files changed, 526 insertions, 0 deletions
diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs
new file mode 100644
index 00000000000..4c3ca62e165
--- /dev/null
+++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs
@@ -0,0 +1,122 @@
+#![feature(move_ref_pattern)]
+
+fn main() {
+    struct S; // Not `Copy`.
+
+    let mut tup0 = (S, S);
+    let mut tup1 = (S, S, S);
+    let tup2 = (S, S);
+    let tup3 = (S, S, S);
+    let tup4 = (S, S);
+    let mut arr0 = [S, S, S];
+    let mut arr1 = [S, S, S, S, S];
+    let arr2 = [S, S, S];
+    let arr3 = [S, S, S, S, S];
+
+    // The `mov` bindings require that we capture the scrutinees by-move.
+    let mut closure = || {
+        // Tuples...
+        let (ref mut borrow, mov) = tup0;
+        let (mov, _, ref mut borrow) = tup1;
+        let (ref borrow, mov) = tup2;
+        let (mov, _, ref borrow) = tup3;
+        let (ref borrow, mov) = tup4;
+        // Arrays...
+        let [mov @ .., ref borrow] = arr0;
+        let [_, ref mut borrow @ .., _, mov] = arr1;
+        let [mov @ .., ref borrow] = arr2;
+        let [_, ref borrow @ .., _, mov] = arr3;
+    };
+
+    // Now we try to borrow and move the captures, which should result in errors...
+    // ...for tuples:
+    drop(&tup0); //~ ERROR borrow of moved value: `tup0`
+    drop(&tup1); //~ ERROR borrow of moved value: `tup1`
+    drop(&tup2); //~ ERROR borrow of moved value: `tup2`
+    drop(&tup3); //~ ERROR borrow of moved value: `tup3`
+    // Ostensibly this should compile.
+    // However, because closures don't capture individual fields, which is changed in RFC 2229,
+    // this won't compile because the entire product is moved into the closure.
+    // The same applies to the array patterns below.
+    drop(&tup4.0); //~ ERROR borrow of moved value: `tup4`
+    // ...for arrays:
+    drop(&arr0); //~ ERROR borrow of moved value: `arr0`
+    let [_, mov1, mov2, mov3, _] = &arr1; //~ ERROR borrow of moved value: `arr1`
+    drop(&arr2); //~ ERROR borrow of moved value: `arr2`
+    let [_, mov1, mov2, mov3, _] = &arr3; //~ ERROR borrow of moved value: `arr3`
+
+    // Let's redo ^--- with a `match` + sum type:
+    macro_rules! m {
+        ($p:pat = $s:expr) => {
+            match $s {
+                Some($p) => {}
+                _ => {}
+            }
+        };
+    }
+    let mut tup0: Option<(S, S)> = None;
+    let mut tup1: Option<(S, S, S)> = None;
+    let tup2: Option<(S, S)> = None;
+    let tup3: Option<(S, S, S)> = None;
+    let tup4: Option<(S, S)> = None;
+    let mut arr0: Option<[S; 3]> = None;
+    let mut arr1: Option<[S; 5]> = None;
+    let arr2: Option<[S; 3]> = None;
+    let arr3: Option<[S; 5]> = None;
+    let mut closure = || {
+        m!((ref mut borrow, mov) = tup0);
+        m!((mov, _, ref mut borrow) = tup1);
+        m!((ref borrow, mov) = tup2);
+        m!((mov, _, ref borrow) = tup3);
+        m!((ref borrow, mov) = tup4);
+        m!([mov @ .., ref borrow] = arr0);
+        m!([_, ref mut borrow @ .., _, mov] = arr1);
+        m!([mov @ .., ref borrow] = arr2);
+        m!([_, ref borrow @ .., _, mov] = arr3);
+    };
+    drop(&tup0); //~ ERROR borrow of moved value: `tup0`
+    drop(&tup1); //~ ERROR borrow of moved value: `tup1`
+    drop(&tup2); //~ ERROR borrow of moved value: `tup2`
+    drop(&tup3); //~ ERROR borrow of moved value: `tup3`
+    m!((ref x, _) = &tup4); //~ ERROR borrow of moved value: `tup4`
+    drop(&arr0); //~ ERROR borrow of moved value: `arr0`
+    m!([_, mov1, mov2, mov3, _] = &arr1); //~ ERROR borrow of moved value: `arr1`
+    drop(&arr2); //~ ERROR borrow of moved value: `arr2`
+    m!([_, mov1, mov2, mov3, _] = &arr3); //~ ERROR borrow of moved value: `arr3`
+
+    // Let's redo ^--- with `if let` (which may diverge from `match` in the future):
+    macro_rules! m {
+        ($p:pat = $s:expr) => {
+            if let Some($p) = $s {}
+        };
+    }
+    let mut tup0: Option<(S, S)> = None;
+    let mut tup1: Option<(S, S, S)> = None;
+    let tup2: Option<(S, S)> = None;
+    let tup3: Option<(S, S, S)> = None;
+    let tup4: Option<(S, S)> = None;
+    let mut arr0: Option<[S; 3]> = None;
+    let mut arr1: Option<[S; 5]> = None;
+    let arr2: Option<[S; 3]> = None;
+    let arr3: Option<[S; 5]> = None;
+    let mut closure = || {
+        m!((ref mut borrow, mov) = tup0);
+        m!((mov, _, ref mut borrow) = tup1);
+        m!((ref borrow, mov) = tup2);
+        m!((mov, _, ref borrow) = tup3);
+        m!((ref borrow, mov) = tup4);
+        m!([mov @ .., ref borrow] = arr0);
+        m!([_, ref mut borrow @ .., _, mov] = arr1);
+        m!([mov @ .., ref borrow] = arr2);
+        m!([_, ref borrow @ .., _, mov] = arr3);
+    };
+    drop(&tup0); //~ ERROR borrow of moved value: `tup0`
+    drop(&tup1); //~ ERROR borrow of moved value: `tup1`
+    drop(&tup2); //~ ERROR borrow of moved value: `tup2`
+    drop(&tup3); //~ ERROR borrow of moved value: `tup3`
+    m!((ref x, _) = &tup4); //~ ERROR borrow of moved value: `tup4`
+    drop(&arr0); //~ ERROR borrow of moved value: `arr0`
+    m!([_, mov1, mov2, mov3, _] = &arr1); //~ ERROR borrow of moved value: `arr1`
+    drop(&arr2); //~ ERROR borrow of moved value: `arr2`
+    m!([_, mov1, mov2, mov3, _] = &arr3); //~ ERROR borrow of moved value: `arr3`
+}
diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.stderr b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.stderr
new file mode 100644
index 00000000000..9159e3e2213
--- /dev/null
+++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.stderr
@@ -0,0 +1,404 @@
+error[E0382]: borrow of moved value: `tup0`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:33:10
+   |
+LL |     let mut tup0 = (S, S);
+   |         -------- move occurs because `tup0` has type `(main::S, main::S)`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+LL |         // Tuples...
+LL |         let (ref mut borrow, mov) = tup0;
+   |                                     ---- variable moved due to use in closure
+...
+LL |     drop(&tup0);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `tup1`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:34:10
+   |
+LL |     let mut tup1 = (S, S, S);
+   |         -------- move occurs because `tup1` has type `(main::S, main::S, main::S)`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         let (mov, _, ref mut borrow) = tup1;
+   |                                        ---- variable moved due to use in closure
+...
+LL |     drop(&tup1);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `tup2`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:35:10
+   |
+LL |     let tup2 = (S, S);
+   |         ---- move occurs because `tup2` has type `(main::S, main::S)`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         let (ref borrow, mov) = tup2;
+   |                                 ---- variable moved due to use in closure
+...
+LL |     drop(&tup2);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `tup3`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:36:10
+   |
+LL |     let tup3 = (S, S, S);
+   |         ---- move occurs because `tup3` has type `(main::S, main::S, main::S)`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         let (mov, _, ref borrow) = tup3;
+   |                                    ---- variable moved due to use in closure
+...
+LL |     drop(&tup3);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `tup4`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:41:10
+   |
+LL |     let tup4 = (S, S);
+   |         ---- move occurs because `tup4` has type `(main::S, main::S)`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         let (ref borrow, mov) = tup4;
+   |                                 ---- variable moved due to use in closure
+...
+LL |     drop(&tup4.0);
+   |          ^^^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `arr0`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:43:10
+   |
+LL |     let mut arr0 = [S, S, S];
+   |         -------- move occurs because `arr0` has type `[main::S; 3]`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         let [mov @ .., ref borrow] = arr0;
+   |                                      ---- variable moved due to use in closure
+...
+LL |     drop(&arr0);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `arr1`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:44:36
+   |
+LL |     let mut arr1 = [S, S, S, S, S];
+   |         -------- move occurs because `arr1` has type `[main::S; 5]`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         let [_, ref mut borrow @ .., _, mov] = arr1;
+   |                                                ---- variable moved due to use in closure
+...
+LL |     let [_, mov1, mov2, mov3, _] = &arr1;
+   |                                    ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `arr2`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:45:10
+   |
+LL |     let arr2 = [S, S, S];
+   |         ---- move occurs because `arr2` has type `[main::S; 3]`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         let [mov @ .., ref borrow] = arr2;
+   |                                      ---- variable moved due to use in closure
+...
+LL |     drop(&arr2);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `arr3`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:46:36
+   |
+LL |     let arr3 = [S, S, S, S, S];
+   |         ---- move occurs because `arr3` has type `[main::S; 5]`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         let [_, ref borrow @ .., _, mov] = arr3;
+   |                                            ---- variable moved due to use in closure
+...
+LL |     let [_, mov1, mov2, mov3, _] = &arr3;
+   |                                    ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `tup0`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:77:10
+   |
+LL |     let mut tup0: Option<(S, S)> = None;
+   |         -------- move occurs because `tup0` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+LL |         m!((ref mut borrow, mov) = tup0);
+   |                                    ---- variable moved due to use in closure
+...
+LL |     drop(&tup0);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `tup1`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:78:10
+   |
+LL |     let mut tup1: Option<(S, S, S)> = None;
+   |         -------- move occurs because `tup1` has type `std::option::Option<(main::S, main::S, main::S)>`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+LL |         m!((ref mut borrow, mov) = tup0);
+LL |         m!((mov, _, ref mut borrow) = tup1);
+   |                                       ---- variable moved due to use in closure
+...
+LL |     drop(&tup1);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `tup2`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:79:10
+   |
+LL |     let tup2: Option<(S, S)> = None;
+   |         ---- move occurs because `tup2` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         m!((ref borrow, mov) = tup2);
+   |                                ---- variable moved due to use in closure
+...
+LL |     drop(&tup2);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `tup3`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:80:10
+   |
+LL |     let tup3: Option<(S, S, S)> = None;
+   |         ---- move occurs because `tup3` has type `std::option::Option<(main::S, main::S, main::S)>`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         m!((mov, _, ref borrow) = tup3);
+   |                                   ---- variable moved due to use in closure
+...
+LL |     drop(&tup3);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `tup4`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:81:21
+   |
+LL |     let tup4: Option<(S, S)> = None;
+   |         ---- move occurs because `tup4` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         m!((ref borrow, mov) = tup4);
+   |                                ---- variable moved due to use in closure
+...
+LL |     m!((ref x, _) = &tup4);
+   |                     ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `arr0`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:82:10
+   |
+LL |     let mut arr0: Option<[S; 3]> = None;
+   |         -------- move occurs because `arr0` has type `std::option::Option<[main::S; 3]>`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         m!([mov @ .., ref borrow] = arr0);
+   |                                     ---- variable moved due to use in closure
+...
+LL |     drop(&arr0);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `arr1`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:83:35
+   |
+LL |     let mut arr1: Option<[S; 5]> = None;
+   |         -------- move occurs because `arr1` has type `std::option::Option<[main::S; 5]>`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         m!([_, ref mut borrow @ .., _, mov] = arr1);
+   |                                               ---- variable moved due to use in closure
+...
+LL |     m!([_, mov1, mov2, mov3, _] = &arr1);
+   |                                   ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `arr2`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:84:10
+   |
+LL |     let arr2: Option<[S; 3]> = None;
+   |         ---- move occurs because `arr2` has type `std::option::Option<[main::S; 3]>`, which does not implement the `Copy` trait
+LL |     let arr3: Option<[S; 5]> = None;
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         m!([mov @ .., ref borrow] = arr2);
+   |                                     ---- variable moved due to use in closure
+...
+LL |     drop(&arr2);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `arr3`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:85:35
+   |
+LL |     let arr3: Option<[S; 5]> = None;
+   |         ---- move occurs because `arr3` has type `std::option::Option<[main::S; 5]>`, which does not implement the `Copy` trait
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         m!([_, ref borrow @ .., _, mov] = arr3);
+   |                                           ---- variable moved due to use in closure
+...
+LL |     m!([_, mov1, mov2, mov3, _] = &arr3);
+   |                                   ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `tup0`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:113:10
+   |
+LL |     let mut tup0: Option<(S, S)> = None;
+   |         -------- move occurs because `tup0` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+LL |         m!((ref mut borrow, mov) = tup0);
+   |                                    ---- variable moved due to use in closure
+...
+LL |     drop(&tup0);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `tup1`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:114:10
+   |
+LL |     let mut tup1: Option<(S, S, S)> = None;
+   |         -------- move occurs because `tup1` has type `std::option::Option<(main::S, main::S, main::S)>`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+LL |         m!((ref mut borrow, mov) = tup0);
+LL |         m!((mov, _, ref mut borrow) = tup1);
+   |                                       ---- variable moved due to use in closure
+...
+LL |     drop(&tup1);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `tup2`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:115:10
+   |
+LL |     let tup2: Option<(S, S)> = None;
+   |         ---- move occurs because `tup2` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         m!((ref borrow, mov) = tup2);
+   |                                ---- variable moved due to use in closure
+...
+LL |     drop(&tup2);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `tup3`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:116:10
+   |
+LL |     let tup3: Option<(S, S, S)> = None;
+   |         ---- move occurs because `tup3` has type `std::option::Option<(main::S, main::S, main::S)>`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         m!((mov, _, ref borrow) = tup3);
+   |                                   ---- variable moved due to use in closure
+...
+LL |     drop(&tup3);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `tup4`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:117:21
+   |
+LL |     let tup4: Option<(S, S)> = None;
+   |         ---- move occurs because `tup4` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         m!((ref borrow, mov) = tup4);
+   |                                ---- variable moved due to use in closure
+...
+LL |     m!((ref x, _) = &tup4);
+   |                     ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `arr0`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:118:10
+   |
+LL |     let mut arr0: Option<[S; 3]> = None;
+   |         -------- move occurs because `arr0` has type `std::option::Option<[main::S; 3]>`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         m!([mov @ .., ref borrow] = arr0);
+   |                                     ---- variable moved due to use in closure
+...
+LL |     drop(&arr0);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `arr1`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:119:35
+   |
+LL |     let mut arr1: Option<[S; 5]> = None;
+   |         -------- move occurs because `arr1` has type `std::option::Option<[main::S; 5]>`, which does not implement the `Copy` trait
+...
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         m!([_, ref mut borrow @ .., _, mov] = arr1);
+   |                                               ---- variable moved due to use in closure
+...
+LL |     m!([_, mov1, mov2, mov3, _] = &arr1);
+   |                                   ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `arr2`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:120:10
+   |
+LL |     let arr2: Option<[S; 3]> = None;
+   |         ---- move occurs because `arr2` has type `std::option::Option<[main::S; 3]>`, which does not implement the `Copy` trait
+LL |     let arr3: Option<[S; 5]> = None;
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         m!([mov @ .., ref borrow] = arr2);
+   |                                     ---- variable moved due to use in closure
+...
+LL |     drop(&arr2);
+   |          ^^^^^ value borrowed here after move
+
+error[E0382]: borrow of moved value: `arr3`
+  --> $DIR/move-ref-patterns-closure-captures-inside.rs:121:35
+   |
+LL |     let arr3: Option<[S; 5]> = None;
+   |         ---- move occurs because `arr3` has type `std::option::Option<[main::S; 5]>`, which does not implement the `Copy` trait
+LL |     let mut closure = || {
+   |                       -- value moved into closure here
+...
+LL |         m!([_, ref borrow @ .., _, mov] = arr3);
+   |                                           ---- variable moved due to use in closure
+...
+LL |     m!([_, mov1, mov2, mov3, _] = &arr3);
+   |                                   ^^^^^ value borrowed here after move
+
+error: aborting due to 27 previous errors
+
+For more information about this error, try `rustc --explain E0382`.