From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- .../move-ref-patterns-closure-captures-inside.rs | 120 +++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs (limited to 'src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs') 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` +} -- cgit v1.2.3