]> git.lizzy.rs Git - rust.git/blob - tests/ui/borrowck/fsu-moves-and-copies.rs
Rollup merge of #106726 - cmorin6:fix-comment-typos, r=Nilstrieb
[rust.git] / tests / ui / borrowck / fsu-moves-and-copies.rs
1 // run-pass
2
3 #![allow(non_camel_case_types)]
4 #![allow(stable_features)]
5 // Issue 4691: Ensure that functional-struct-updates operates
6 // correctly and moves rather than copy when appropriate.
7
8 #![feature(core)]
9
10 struct ncint { v: isize }
11 fn ncint(v: isize) -> ncint { ncint { v: v } }
12
13 struct NoFoo { copied: isize, nocopy: ncint, }
14 impl NoFoo {
15     fn new(x:isize,y:isize) -> NoFoo { NoFoo { copied: x, nocopy: ncint(y) } }
16 }
17
18 struct MoveFoo { copied: isize, moved: Box<isize>, }
19 impl MoveFoo {
20     fn new(x:isize,y:isize) -> MoveFoo { MoveFoo { copied: x, moved: Box::new(y) } }
21 }
22
23 struct DropNoFoo { inner: NoFoo }
24 impl DropNoFoo {
25     fn new(x:isize,y:isize) -> DropNoFoo { DropNoFoo { inner: NoFoo::new(x,y) } }
26 }
27 impl Drop for DropNoFoo { fn drop(&mut self) { } }
28
29 struct DropMoveFoo { inner: MoveFoo }
30 impl DropMoveFoo {
31     fn new(x:isize,y:isize) -> DropMoveFoo { DropMoveFoo { inner: MoveFoo::new(x,y) } }
32 }
33 impl Drop for DropMoveFoo { fn drop(&mut self) { } }
34
35
36 fn test0() {
37     // just copy implicitly copyable fields from `f`, no moves
38     // (and thus it is okay that these are Drop; compare against
39     // test ui/borrowck/borrowck-struct-update-with-dtor.rs).
40
41     // Case 1: Nocopyable
42     let f = DropNoFoo::new(1, 2);
43     let b = DropNoFoo { inner: NoFoo { nocopy: ncint(3), ..f.inner }};
44     let c = DropNoFoo { inner: NoFoo { nocopy: ncint(4), ..f.inner }};
45     assert_eq!(f.inner.copied,    1);
46     assert_eq!(f.inner.nocopy.v, 2);
47
48     assert_eq!(b.inner.copied,    1);
49     assert_eq!(b.inner.nocopy.v, 3);
50
51     assert_eq!(c.inner.copied,    1);
52     assert_eq!(c.inner.nocopy.v, 4);
53
54     // Case 2: Owned
55     let f = DropMoveFoo::new(5, 6);
56     let b = DropMoveFoo { inner: MoveFoo { moved: Box::new(7), ..f.inner }};
57     let c = DropMoveFoo { inner: MoveFoo { moved: Box::new(8), ..f.inner }};
58     assert_eq!(f.inner.copied,    5);
59     assert_eq!(*f.inner.moved,    6);
60
61     assert_eq!(b.inner.copied,    5);
62     assert_eq!(*b.inner.moved,    7);
63
64     assert_eq!(c.inner.copied,    5);
65     assert_eq!(*c.inner.moved,    8);
66 }
67
68 fn test1() {
69     // copying move-by-default fields from `f`, so it moves:
70     let f = MoveFoo::new(11, 12);
71
72     let b = MoveFoo {moved: Box::new(13), ..f};
73     let c = MoveFoo {copied: 14, ..f};
74     assert_eq!(b.copied,    11);
75     assert_eq!(*b.moved,    13);
76     assert_eq!(c.copied,    14);
77     assert_eq!(*c.moved,    12);
78 }
79
80 fn test2() {
81     // move non-copyable field
82     let f = NoFoo::new(21, 22);
83     let b = NoFoo {nocopy: ncint(23), ..f};
84     let c = NoFoo {copied: 24, ..f};
85     assert_eq!(b.copied,    21);
86     assert_eq!(b.nocopy.v, 23);
87     assert_eq!(c.copied,    24);
88     assert_eq!(c.nocopy.v, 22);
89 }
90
91 pub fn main() {
92     test0();
93     test1();
94     test2();
95 }