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.
15 #![allow(unknown_features)]
16 #![feature(box_syntax, core)]
18 struct ncint { v: isize }
19 fn ncint(v: isize) -> ncint { ncint { v: v } }
21 struct NoFoo { copied: isize, nocopy: ncint, }
23 fn new(x:isize,y:isize) -> NoFoo { NoFoo { copied: x, nocopy: ncint(y) } }
26 struct MoveFoo { copied: isize, moved: Box<isize>, }
28 fn new(x:isize,y:isize) -> MoveFoo { MoveFoo { copied: x, moved: box y } }
31 struct DropNoFoo { inner: NoFoo }
33 fn new(x:isize,y:isize) -> DropNoFoo { DropNoFoo { inner: NoFoo::new(x,y) } }
35 impl Drop for DropNoFoo { fn drop(&mut self) { } }
37 struct DropMoveFoo { inner: MoveFoo }
39 fn new(x:isize,y:isize) -> DropMoveFoo { DropMoveFoo { inner: MoveFoo::new(x,y) } }
41 impl Drop for DropMoveFoo { fn drop(&mut self) { } }
45 // just copy implicitly copyable fields from `f`, no moves
46 // (and thus it is okay that these are Drop; compare against
47 // compile-fail test: borrowck-struct-update-with-dtor.rs).
50 let f = DropNoFoo::new(1, 2);
51 let b = DropNoFoo { inner: NoFoo { nocopy: ncint(3), ..f.inner }};
52 let c = DropNoFoo { inner: NoFoo { nocopy: ncint(4), ..f.inner }};
53 assert_eq!(f.inner.copied, 1);
54 assert_eq!(f.inner.nocopy.v, 2);
56 assert_eq!(b.inner.copied, 1);
57 assert_eq!(b.inner.nocopy.v, 3);
59 assert_eq!(c.inner.copied, 1);
60 assert_eq!(c.inner.nocopy.v, 4);
63 let f = DropMoveFoo::new(5, 6);
64 let b = DropMoveFoo { inner: MoveFoo { moved: box 7, ..f.inner }};
65 let c = DropMoveFoo { inner: MoveFoo { moved: box 8, ..f.inner }};
66 assert_eq!(f.inner.copied, 5);
67 assert_eq!(*f.inner.moved, 6);
69 assert_eq!(b.inner.copied, 5);
70 assert_eq!(*b.inner.moved, 7);
72 assert_eq!(c.inner.copied, 5);
73 assert_eq!(*c.inner.moved, 8);
77 // copying move-by-default fields from `f`, so it moves:
78 let f = MoveFoo::new(11, 12);
80 let b = MoveFoo {moved: box 13, ..f};
81 let c = MoveFoo {copied: 14, ..f};
82 assert_eq!(b.copied, 11);
83 assert_eq!(*b.moved, 13);
84 assert_eq!(c.copied, 14);
85 assert_eq!(*c.moved, 12);
89 // move non-copyable field
90 let f = NoFoo::new(21, 22);
91 let b = NoFoo {nocopy: ncint(23), ..f};
92 let c = NoFoo {copied: 24, ..f};
93 assert_eq!(b.copied, 21);
94 assert_eq!(b.nocopy.v, 23);
95 assert_eq!(c.copied, 24);
96 assert_eq!(c.nocopy.v, 22);