Skip to content

Commit 2f68d93

Browse files
committed
---
yaml --- r: 60349 b: refs/heads/master c: 75822f2 h: refs/heads/master i: 60347: df05faf v: v3
1 parent dca4219 commit 2f68d93

File tree

7 files changed

+130
-20
lines changed

7 files changed

+130
-20
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 31cedf6927ae4add985995137c394032b599ea1e
2+
refs/heads/master: 75822f2894498025d6a86bcaf30fa56118c7d3ab
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 2d28d645422c1617be58c8ca7ad9a457264ca850
55
refs/heads/try: c50a9d5b664478e533ba1d1d353213d70c8ad589

trunk/src/libcore/clone.rs

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,12 @@ by convention implementing the `Clone` trait and calling the
2323
*/
2424

2525
pub trait Clone {
26-
/// Return a deep copy of the owned object tree. Managed boxes are cloned with a shallow copy.
26+
/// Return a deep copy of the owned object tree. Types with shared ownership like managed boxes
27+
/// are cloned with a shallow copy.
2728
fn clone(&self) -> Self;
2829
}
2930

30-
impl Clone for () {
31-
/// Return a copy of the value.
32-
#[inline(always)]
33-
fn clone(&self) -> () { () }
34-
}
35-
36-
impl<T:Clone> Clone for ~T {
31+
impl<T: Clone> Clone for ~T {
3732
/// Return a deep copy of the owned box.
3833
#[inline(always)]
3934
fn clone(&self) -> ~T { ~(**self).clone() }
@@ -54,7 +49,7 @@ impl<T> Clone for @mut T {
5449
macro_rules! clone_impl(
5550
($t:ty) => {
5651
impl Clone for $t {
57-
/// Return a copy of the value.
52+
/// Return a deep copy of the value.
5853
#[inline(always)]
5954
fn clone(&self) -> $t { *self }
6055
}
@@ -77,9 +72,53 @@ clone_impl!(float)
7772
clone_impl!(f32)
7873
clone_impl!(f64)
7974

75+
clone_impl!(())
8076
clone_impl!(bool)
8177
clone_impl!(char)
8278

79+
pub trait DeepClone {
80+
/// Return a deep copy of the object tree. Types with shared ownership are also copied via a
81+
/// deep copy, unlike `Clone`. Note that this is currently unimplemented for managed boxes, as
82+
/// it would need to handle cycles.
83+
fn deep_clone(&self) -> Self;
84+
}
85+
86+
macro_rules! deep_clone_impl(
87+
($t:ty) => {
88+
impl DeepClone for $t {
89+
/// Return a deep copy of the value.
90+
#[inline(always)]
91+
fn deep_clone(&self) -> $t { *self }
92+
}
93+
}
94+
)
95+
96+
impl<T: DeepClone> DeepClone for ~T {
97+
/// Return a deep copy of the owned box.
98+
#[inline(always)]
99+
fn deep_clone(&self) -> ~T { ~(**self).deep_clone() }
100+
}
101+
102+
deep_clone_impl!(int)
103+
deep_clone_impl!(i8)
104+
deep_clone_impl!(i16)
105+
deep_clone_impl!(i32)
106+
deep_clone_impl!(i64)
107+
108+
deep_clone_impl!(uint)
109+
deep_clone_impl!(u8)
110+
deep_clone_impl!(u16)
111+
deep_clone_impl!(u32)
112+
deep_clone_impl!(u64)
113+
114+
deep_clone_impl!(float)
115+
deep_clone_impl!(f32)
116+
deep_clone_impl!(f64)
117+
118+
deep_clone_impl!(())
119+
deep_clone_impl!(bool)
120+
deep_clone_impl!(char)
121+
83122
#[test]
84123
fn test_owned_clone() {
85124
let a: ~int = ~5i;

trunk/src/libcore/prelude.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub use io::{print, println};
2727

2828
/* Reexported types and traits */
2929

30-
pub use clone::Clone;
30+
pub use clone::{Clone, DeepClone};
3131
pub use cmp::{Eq, ApproxEq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater, Equiv};
3232
pub use container::{Container, Mutable, Map, Set};
3333
pub use hash::Hash;

trunk/src/libcore/to_bytes.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,6 @@ pub fn iter_bytes_2<A:IterBytes,B:IterBytes>(a: &A, b: &B,
458458
b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
459459
}
460460
#[cfg(not(stage0))]
461-
#[inline(always)]
462461
pub fn iter_bytes_2<A:IterBytes,B:IterBytes>(a: &A, b: &B,
463462
lsb0: bool, z: Cb) -> bool {
464463
a.iter_bytes(lsb0, z) && b.iter_bytes(lsb0, z)

trunk/src/libstd/rc.rs

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ impl<T: Owned> Drop for Rc<T> {
7676

7777

7878
impl<T: Owned> Clone for Rc<T> {
79+
/// Return a shallow copy of the reference counted pointer.
7980
#[inline]
8081
fn clone(&self) -> Rc<T> {
8182
unsafe {
@@ -85,9 +86,46 @@ impl<T: Owned> Clone for Rc<T> {
8586
}
8687
}
8788

89+
impl<T: Owned + DeepClone> DeepClone for Rc<T> {
90+
/// Return a deep copy of the reference counted pointer.
91+
#[inline]
92+
fn deep_clone(&self) -> Rc<T> {
93+
Rc::new(self.borrow().deep_clone())
94+
}
95+
}
96+
8897
#[cfg(test)]
8998
mod test_rc {
9099
use super::*;
100+
use core::cell::Cell;
101+
102+
#[test]
103+
fn test_clone() {
104+
let x = Rc::new(Cell(5));
105+
let y = x.clone();
106+
do x.with_borrow |cell| {
107+
do value.with_mut_ref |inner| {
108+
*inner = 20;
109+
}
110+
}
111+
do y.with_borrow |value| {
112+
assert_eq!(value.take(), 20);
113+
}
114+
}
115+
116+
#[test]
117+
fn test_deep_clone() {
118+
let x = Rc::new(Cell(5));
119+
let y = x.deep_clone();
120+
do x.with_borrow |cell| {
121+
do value.with_mut_ref |inner| {
122+
*inner = 20;
123+
}
124+
}
125+
do y.with_borrow |value| {
126+
assert_eq!(value.take(), 5);
127+
}
128+
}
91129

92130
#[test]
93131
fn test_simple() {
@@ -149,24 +187,26 @@ pub impl<T: Owned> RcMut<T> {
149187

150188
/// Fails if there is already a mutable borrow of the box
151189
#[inline]
152-
fn with_borrow(&self, f: &fn(&T)) {
190+
fn with_borrow<U>(&self, f: &fn(&T) -> U) -> U {
153191
unsafe {
154192
assert!((*self.ptr).borrow != Mutable);
155193
let previous = (*self.ptr).borrow;
156194
(*self.ptr).borrow = Immutable;
157-
f(&(*self.ptr).value);
195+
let res = f(&(*self.ptr).value);
158196
(*self.ptr).borrow = previous;
197+
res
159198
}
160199
}
161200

162201
/// Fails if there is already a mutable or immutable borrow of the box
163202
#[inline]
164-
fn with_mut_borrow(&self, f: &fn(&mut T)) {
203+
fn with_mut_borrow<U>(&self, f: &fn(&mut T) -> U) -> U {
165204
unsafe {
166205
assert!((*self.ptr).borrow == Nothing);
167206
(*self.ptr).borrow = Mutable;
168-
f(&mut (*self.ptr).value);
207+
let res = f(&mut (*self.ptr).value);
169208
(*self.ptr).borrow = Nothing;
209+
res
170210
}
171211
}
172212
}
@@ -200,6 +240,7 @@ impl<T: Owned> Drop for RcMut<T> {
200240
}
201241

202242
impl<T: Owned> Clone for RcMut<T> {
243+
/// Return a shallow copy of the reference counted pointer.
203244
#[inline]
204245
fn clone(&self) -> RcMut<T> {
205246
unsafe {
@@ -209,10 +250,45 @@ impl<T: Owned> Clone for RcMut<T> {
209250
}
210251
}
211252

253+
impl<T: Owned + DeepClone> DeepClone for RcMut<T> {
254+
/// Return a deep copy of the reference counted pointer.
255+
#[inline]
256+
fn deep_clone(&self) -> RcMut<T> {
257+
do self.with_borrow |x| {
258+
// FIXME: #6497: should avoid freeze (slow)
259+
RcMut::new(x.deep_clone())
260+
}
261+
}
262+
}
263+
212264
#[cfg(test)]
213265
mod test_rc_mut {
214266
use super::*;
215267

268+
#[test]
269+
fn test_clone() {
270+
let x = RcMut::new(5);
271+
let y = x.clone();
272+
do x.with_mut_borrow |value| {
273+
*value = 20;
274+
}
275+
do y.with_borrow |value| {
276+
assert_eq!(*value, 20);
277+
}
278+
}
279+
280+
#[test]
281+
fn test_deep_clone() {
282+
let x = RcMut::new(5);
283+
let y = x.deep_clone();
284+
do x.with_mut_borrow |value| {
285+
*value = 20;
286+
}
287+
do y.with_borrow |value| {
288+
assert_eq!(*value, 5);
289+
}
290+
}
291+
216292
#[test]
217293
fn borrow_many() {
218294
let x = RcMut::new(5);

trunk/src/libsyntax/ast.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,12 @@ impl<D:Decoder> Decodable<D> for ident {
9898

9999
#[cfg(stage0)]
100100
impl to_bytes::IterBytes for ident {
101-
#[inline(always)]
102101
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
103102
self.repr.iter_bytes(lsb0, f)
104103
}
105104
}
106105
#[cfg(not(stage0))]
107106
impl to_bytes::IterBytes for ident {
108-
#[inline(always)]
109107
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
110108
self.repr.iter_bytes(lsb0, f)
111109
}

trunk/src/libsyntax/parse/token.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,14 +357,12 @@ impl<'self> Equiv<@~str> for StringRef<'self> {
357357

358358
#[cfg(stage0)]
359359
impl<'self> to_bytes::IterBytes for StringRef<'self> {
360-
#[inline(always)]
361360
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
362361
(**self).iter_bytes(lsb0, f);
363362
}
364363
}
365364
#[cfg(not(stage0))]
366365
impl<'self> to_bytes::IterBytes for StringRef<'self> {
367-
#[inline(always)]
368366
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
369367
(**self).iter_bytes(lsb0, f)
370368
}

0 commit comments

Comments
 (0)