summaryrefslogtreecommitdiffstats
path: root/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs')
-rw-r--r--src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs120
1 files changed, 120 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 000000000..ebb1683af
--- /dev/null
+++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs
@@ -0,0 +1,120 @@
+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`
+}