]> git.proxmox.com Git - rustc.git/blob - src/test/run-pass/fsu-moves-and-copies.rs
Imported Upstream version 1.0.0~0alpha
[rustc.git] / src / test / run-pass / fsu-moves-and-copies.rs
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.
4 //
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.
10
11 // Issue 4691: Ensure that functional-struct-updates operates
12 // correctly and moves rather than copy when appropriate.
13
14 #![allow(unknown_features)]
15 #![feature(box_syntax)]
16
17 use std::marker::NoCopy as NP;
18
19 struct ncint { np: NP, v: int }
20 fn ncint(v: int) -> ncint { ncint { np: NP, v: v } }
21
22 struct NoFoo { copied: int, nocopy: ncint, }
23 impl NoFoo {
24 fn new(x:int,y:int) -> NoFoo { NoFoo { copied: x, nocopy: ncint(y) } }
25 }
26
27 struct MoveFoo { copied: int, moved: Box<int>, }
28 impl MoveFoo {
29 fn new(x:int,y:int) -> MoveFoo { MoveFoo { copied: x, moved: box y } }
30 }
31
32 struct DropNoFoo { inner: NoFoo }
33 impl DropNoFoo {
34 fn new(x:int,y:int) -> DropNoFoo { DropNoFoo { inner: NoFoo::new(x,y) } }
35 }
36 impl Drop for DropNoFoo { fn drop(&mut self) { } }
37
38 struct DropMoveFoo { inner: MoveFoo }
39 impl DropMoveFoo {
40 fn new(x:int,y:int) -> DropMoveFoo { DropMoveFoo { inner: MoveFoo::new(x,y) } }
41 }
42 impl Drop for DropMoveFoo { fn drop(&mut self) { } }
43
44
45 fn test0() {
46 // just copy implicitly copyable fields from `f`, no moves
47 // (and thus it is okay that these are Drop; compare against
48 // compile-fail test: borrowck-struct-update-with-dtor.rs).
49
50 // Case 1: Nocopyable
51 let f = DropNoFoo::new(1, 2);
52 let b = DropNoFoo { inner: NoFoo { nocopy: ncint(3), ..f.inner }};
53 let c = DropNoFoo { inner: NoFoo { nocopy: ncint(4), ..f.inner }};
54 assert_eq!(f.inner.copied, 1);
55 assert_eq!(f.inner.nocopy.v, 2);
56
57 assert_eq!(b.inner.copied, 1);
58 assert_eq!(b.inner.nocopy.v, 3);
59
60 assert_eq!(c.inner.copied, 1);
61 assert_eq!(c.inner.nocopy.v, 4);
62
63 // Case 2: Owned
64 let f = DropMoveFoo::new(5, 6);
65 let b = DropMoveFoo { inner: MoveFoo { moved: box 7, ..f.inner }};
66 let c = DropMoveFoo { inner: MoveFoo { moved: box 8, ..f.inner }};
67 assert_eq!(f.inner.copied, 5);
68 assert_eq!(*f.inner.moved, 6);
69
70 assert_eq!(b.inner.copied, 5);
71 assert_eq!(*b.inner.moved, 7);
72
73 assert_eq!(c.inner.copied, 5);
74 assert_eq!(*c.inner.moved, 8);
75 }
76
77 fn test1() {
78 // copying move-by-default fields from `f`, so it moves:
79 let f = MoveFoo::new(11, 12);
80
81 let b = MoveFoo {moved: box 13, ..f};
82 let c = MoveFoo {copied: 14, ..f};
83 assert_eq!(b.copied, 11);
84 assert_eq!(*b.moved, 13);
85 assert_eq!(c.copied, 14);
86 assert_eq!(*c.moved, 12);
87 }
88
89 fn test2() {
90 // move non-copyable field
91 let f = NoFoo::new(21, 22);
92 let b = NoFoo {nocopy: ncint(23), ..f};
93 let c = NoFoo {copied: 24, ..f};
94 assert_eq!(b.copied, 21);
95 assert_eq!(b.nocopy.v, 23);
96 assert_eq!(c.copied, 24);
97 assert_eq!(c.nocopy.v, 22);
98 }
99
100 pub fn main() {
101 test0();
102 test1();
103 test2();
104 }