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.
10 struct ncint { v: isize }
11 fn ncint(v: isize) -> ncint { ncint { v: v } }
13 struct NoFoo { copied: isize, nocopy: ncint, }
15 fn new(x:isize,y:isize) -> NoFoo { NoFoo { copied: x, nocopy: ncint(y) } }
18 struct MoveFoo { copied: isize, moved: Box<isize>, }
20 fn new(x:isize,y:isize) -> MoveFoo { MoveFoo { copied: x, moved: Box::new(y) } }
23 struct DropNoFoo { inner: NoFoo }
25 fn new(x:isize,y:isize) -> DropNoFoo { DropNoFoo { inner: NoFoo::new(x,y) } }
27 impl Drop for DropNoFoo { fn drop(&mut self) { } }
29 struct DropMoveFoo { inner: MoveFoo }
31 fn new(x:isize,y:isize) -> DropMoveFoo { DropMoveFoo { inner: MoveFoo::new(x,y) } }
33 impl Drop for DropMoveFoo { fn drop(&mut self) { } }
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).
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);
48 assert_eq!(b.inner.copied, 1);
49 assert_eq!(b.inner.nocopy.v, 3);
51 assert_eq!(c.inner.copied, 1);
52 assert_eq!(c.inner.nocopy.v, 4);
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);
61 assert_eq!(b.inner.copied, 5);
62 assert_eq!(*b.inner.moved, 7);
64 assert_eq!(c.inner.copied, 5);
65 assert_eq!(*c.inner.moved, 8);
69 // copying move-by-default fields from `f`, so it moves:
70 let f = MoveFoo::new(11, 12);
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);
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);