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 #![allow(unknown_features)]
15 #![feature(box_syntax)]
17 use std
::marker
::NoCopy
as NP
;
19 struct ncint { np: NP, v: int }
20 fn ncint(v
: int
) -> ncint { ncint { np: NP, v: v }
}
22 struct NoFoo { copied: int, nocopy: ncint, }
24 fn new(x
:int
,y
:int
) -> NoFoo { NoFoo { copied: x, nocopy: ncint(y) }
}
27 struct MoveFoo { copied: int, moved: Box<int>, }
29 fn new(x
:int
,y
:int
) -> MoveFoo { MoveFoo { copied: x, moved: box y }
}
32 struct DropNoFoo { inner: NoFoo }
34 fn new(x
:int
,y
:int
) -> DropNoFoo { DropNoFoo { inner: NoFoo::new(x,y) }
}
36 impl Drop
for DropNoFoo { fn drop(&mut self) { }
}
38 struct DropMoveFoo { inner: MoveFoo }
40 fn new(x
:int
,y
:int
) -> DropMoveFoo { DropMoveFoo { inner: MoveFoo::new(x,y) }
}
42 impl Drop
for DropMoveFoo { fn drop(&mut self) { }
}
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).
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);
57 assert_eq
!(b
.inner
.copied
, 1);
58 assert_eq
!(b
.inner
.nocopy
.v
, 3);
60 assert_eq
!(c
.inner
.copied
, 1);
61 assert_eq
!(c
.inner
.nocopy
.v
, 4);
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);
70 assert_eq
!(b
.inner
.copied
, 5);
71 assert_eq
!(*b
.inner
.moved
, 7);
73 assert_eq
!(c
.inner
.copied
, 5);
74 assert_eq
!(*c
.inner
.moved
, 8);
78 // copying move-by-default fields from `f`, so it moves:
79 let f
= MoveFoo
::new(11, 12);
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);
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);