1 // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 // Issue 4691: Ensure that functional-struct-updates operates
12 // correctly and moves rather than copy when appropriate.
14 #![feature(box_syntax, core)]
16 struct ncint { v: isize }
17 fn ncint(v: isize) -> ncint { ncint { v: v } }
19 struct NoFoo { copied: isize, nocopy: ncint, }
21 fn new(x:isize,y:isize) -> NoFoo { NoFoo { copied: x, nocopy: ncint(y) } }
24 struct MoveFoo { copied: isize, moved: Box<isize>, }
26 fn new(x:isize,y:isize) -> MoveFoo { MoveFoo { copied: x, moved: box y } }
29 struct DropNoFoo { inner: NoFoo }
31 fn new(x:isize,y:isize) -> DropNoFoo { DropNoFoo { inner: NoFoo::new(x,y) } }
33 impl Drop for DropNoFoo { fn drop(&mut self) { } }
35 struct DropMoveFoo { inner: MoveFoo }
37 fn new(x:isize,y:isize) -> DropMoveFoo { DropMoveFoo { inner: MoveFoo::new(x,y) } }
39 impl Drop for DropMoveFoo { fn drop(&mut self) { } }
43 // just copy implicitly copyable fields from `f`, no moves
44 // (and thus it is okay that these are Drop; compare against
45 // compile-fail test: borrowck-struct-update-with-dtor.rs).
48 let f = DropNoFoo::new(1, 2);
49 let b = DropNoFoo { inner: NoFoo { nocopy: ncint(3), ..f.inner }};
50 let c = DropNoFoo { inner: NoFoo { nocopy: ncint(4), ..f.inner }};
51 assert_eq!(f.inner.copied, 1);
52 assert_eq!(f.inner.nocopy.v, 2);
54 assert_eq!(b.inner.copied, 1);
55 assert_eq!(b.inner.nocopy.v, 3);
57 assert_eq!(c.inner.copied, 1);
58 assert_eq!(c.inner.nocopy.v, 4);
61 let f = DropMoveFoo::new(5, 6);
62 let b = DropMoveFoo { inner: MoveFoo { moved: box 7, ..f.inner }};
63 let c = DropMoveFoo { inner: MoveFoo { moved: box 8, ..f.inner }};
64 assert_eq!(f.inner.copied, 5);
65 assert_eq!(*f.inner.moved, 6);
67 assert_eq!(b.inner.copied, 5);
68 assert_eq!(*b.inner.moved, 7);
70 assert_eq!(c.inner.copied, 5);
71 assert_eq!(*c.inner.moved, 8);
75 // copying move-by-default fields from `f`, so it moves:
76 let f = MoveFoo::new(11, 12);
78 let b = MoveFoo {moved: box 13, ..f};
79 let c = MoveFoo {copied: 14, ..f};
80 assert_eq!(b.copied, 11);
81 assert_eq!(*b.moved, 13);
82 assert_eq!(c.copied, 14);
83 assert_eq!(*c.moved, 12);
87 // move non-copyable field
88 let f = NoFoo::new(21, 22);
89 let b = NoFoo {nocopy: ncint(23), ..f};
90 let c = NoFoo {copied: 24, ..f};
91 assert_eq!(b.copied, 21);
92 assert_eq!(b.nocopy.v, 23);
93 assert_eq!(c.copied, 24);
94 assert_eq!(c.nocopy.v, 22);