Skip to content

impl Clone for ~T, ~[T], ~str #5404

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/libcore/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ impl Clone for () {
fn clone(&self) -> () { () }
}

impl<T:Clone> Clone for ~T {
#[inline(always)]
fn clone(&self) -> ~T { ~(**self).clone() }
}

macro_rules! clone_impl(
($t:ty) => {
impl Clone for $t {
Expand Down
8 changes: 8 additions & 0 deletions src/libcore/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use at_vec;
use cast;
use char;
use clone::Clone;
use cmp::{Equiv, TotalOrd, Ordering, Less, Equal, Greater};
use libc;
use option::{None, Option, Some};
Expand Down Expand Up @@ -2433,6 +2434,13 @@ impl OwnedStr for ~str {
}
}

impl Clone for ~str {
#[inline(always)]
fn clone(&self) -> ~str {
self.to_str() // hilarious
}
}

#[cfg(test)]
mod tests {
use char;
Expand Down
6 changes: 3 additions & 3 deletions src/libcore/unstable/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ unsafe fn global_data_clone_create_<T:Owned + Clone>(
match value {
None => {
let value = create();
clone_value = Some(value.clone());
clone_value = Some((*value).clone());
Some(value)
}
Some(value) => {
clone_value = Some(value.clone());
clone_value = Some((*value).clone());
Some(value)
}
}
Expand Down Expand Up @@ -193,7 +193,7 @@ fn get_global_state() -> Exclusive<GlobalState> {
// Successfully installed the global pointer

// Take a handle to return
let clone = state.clone();
let clone = (*state).clone();

// Install a runtime exit function to destroy the global object
do at_exit {
Expand Down
13 changes: 13 additions & 0 deletions src/libcore/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use container::{Container, Mutable};
use cast;
use cmp::{Eq, Equiv, Ord, TotalOrd, Ordering, Less, Equal, Greater};
use clone::Clone;
use iter::BaseIter;
use iter;
use kinds::Copy;
Expand Down Expand Up @@ -2501,6 +2502,18 @@ impl<A:Copy> iter::CopyableNonstrictIter<A> for @[A] {
}
}

impl<A:Clone> Clone for ~[A] {
#[inline]
fn clone(&self) -> ~[A] {
let mut dolly = ~[];
vec::reserve(&mut dolly, self.len());
for self.each |item| {
dolly.push(item.clone());
}
return dolly;
}
}

// ___________________________________________________________________________

#[cfg(test)]
Expand Down
20 changes: 10 additions & 10 deletions src/libstd/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ mod tests {
#[test] #[should_fail] #[ignore(cfg(windows))]
pub fn test_rw_arc_poison_wr() {
let arc = ~RWARC(1);
let arc2 = ~arc.clone();
let arc2 = (*arc).clone();
do task::try || {
do arc2.write |one| {
fail_unless!(*one == 2);
Expand All @@ -585,7 +585,7 @@ mod tests {
#[test] #[should_fail] #[ignore(cfg(windows))]
pub fn test_rw_arc_poison_ww() {
let arc = ~RWARC(1);
let arc2 = ~arc.clone();
let arc2 = (*arc).clone();
do task::try || {
do arc2.write |one| {
fail_unless!(*one == 2);
Expand All @@ -598,7 +598,7 @@ mod tests {
#[test] #[should_fail] #[ignore(cfg(windows))]
pub fn test_rw_arc_poison_dw() {
let arc = ~RWARC(1);
let arc2 = ~arc.clone();
let arc2 = (*arc).clone();
do task::try || {
do arc2.write_downgrade |write_mode| {
do (&write_mode).write |one| {
Expand All @@ -613,7 +613,7 @@ mod tests {
#[test] #[ignore(cfg(windows))]
pub fn test_rw_arc_no_poison_rr() {
let arc = ~RWARC(1);
let arc2 = ~arc.clone();
let arc2 = (*arc).clone();
do task::try || {
do arc2.read |one| {
fail_unless!(*one == 2);
Expand All @@ -626,7 +626,7 @@ mod tests {
#[test] #[ignore(cfg(windows))]
pub fn test_rw_arc_no_poison_rw() {
let arc = ~RWARC(1);
let arc2 = ~arc.clone();
let arc2 = (*arc).clone();
do task::try || {
do arc2.read |one| {
fail_unless!(*one == 2);
Expand All @@ -639,7 +639,7 @@ mod tests {
#[test] #[ignore(cfg(windows))]
pub fn test_rw_arc_no_poison_dr() {
let arc = ~RWARC(1);
let arc2 = ~arc.clone();
let arc2 = (*arc).clone();
do task::try || {
do arc2.write_downgrade |write_mode| {
let read_mode = arc2.downgrade(write_mode);
Expand All @@ -655,7 +655,7 @@ mod tests {
#[test]
pub fn test_rw_arc() {
let arc = ~RWARC(0);
let arc2 = ~arc.clone();
let arc2 = (*arc).clone();
let (p,c) = comm::stream();

do task::spawn || {
Expand All @@ -673,7 +673,7 @@ mod tests {
// Readers try to catch the writer in the act
let mut children = ~[];
for 5.times {
let arc3 = ~arc.clone();
let arc3 = (*arc).clone();
do task::task().future_result(|+r| children.push(r)).spawn
|| {
do arc3.read |num| {
Expand Down Expand Up @@ -704,7 +704,7 @@ mod tests {
for 10.times {
let ((rp1,rc1),(rp2,rc2)) = (comm::stream(),comm::stream());
reader_convos.push((rc1, rp2));
let arcn = ~arc.clone();
let arcn = (*arc).clone();
do task::spawn || {
rp1.recv(); // wait for downgrader to give go-ahead
do arcn.read |state| {
Expand All @@ -715,7 +715,7 @@ mod tests {
}

// Writer task
let arc2 = ~arc.clone();
let arc2 = (*arc).clone();
let ((wp1,wc1),(wp2,wc2)) = (comm::stream(),comm::stream());
do task::spawn || {
wp1.recv();
Expand Down
22 changes: 11 additions & 11 deletions src/libstd/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ mod tests {
// "load tmp = move ptr; inc tmp; store ptr <- tmp" dance.
let (p,c) = comm::stream();
let m = ~Mutex();
let m2 = ~m.clone();
let m2 = m.clone();
let mut sharedstate = ~0;
let ptr = ptr::addr_of(&(*sharedstate));
do task::spawn || {
Expand Down Expand Up @@ -1105,13 +1105,13 @@ mod tests {
// Test mutual exclusion between readers and writers. Just like the
// mutex mutual exclusion test, a ways above.
let (p,c) = comm::stream();
let x2 = ~x.clone();
let x2 = (*x).clone();
let mut sharedstate = ~0;
let ptr = ptr::addr_of(&(*sharedstate));
do task::spawn || {
let sharedstate: &mut int =
unsafe { cast::reinterpret_cast(&ptr) };
access_shared(sharedstate, x2, mode1, 10);
access_shared(sharedstate, &x2, mode1, 10);
c.send(());
}
access_shared(sharedstate, x, mode2, 10);
Expand Down Expand Up @@ -1150,14 +1150,14 @@ mod tests {
mode2: RWlockMode,
make_mode2_go_first: bool) {
// Much like sem_multi_resource.
let x2 = ~x.clone();
let x2 = (*x).clone();
let (p1,c1) = comm::stream();
let (p2,c2) = comm::stream();
do task::spawn || {
if !make_mode2_go_first {
let _ = p2.recv(); // parent sends to us once it locks, or ...
}
do lock_rwlock_in_mode(x2, mode2) {
do lock_rwlock_in_mode(&x2, mode2) {
if make_mode2_go_first {
c1.send(()); // ... we send to it once we lock
}
Expand Down Expand Up @@ -1207,7 +1207,7 @@ mod tests {

// Child wakes up parent
do x.write_cond |cond| {
let x2 = ~x.clone();
let x2 = (*x).clone();
do task::spawn || {
do x2.write_cond |cond| {
let woken = cond.signal();
Expand All @@ -1218,7 +1218,7 @@ mod tests {
}
// Parent wakes up child
let (port,chan) = comm::stream();
let x3 = ~x.clone();
let x3 = (*x).clone();
do task::spawn || {
do x3.write_cond |cond| {
chan.send(());
Expand Down Expand Up @@ -1253,11 +1253,11 @@ mod tests {
let mut ports = ~[];

for num_waiters.times {
let xi = ~x.clone();
let xi = (*x).clone();
let (port, chan) = comm::stream();
ports.push(port);
do task::spawn || {
do lock_cond(xi, dg1) |cond| {
do lock_cond(&xi, dg1) |cond| {
chan.send(());
cond.wait();
chan.send(());
Expand Down Expand Up @@ -1289,10 +1289,10 @@ mod tests {
pub fn rwlock_kill_helper(mode1: RWlockMode, mode2: RWlockMode) {
// Mutex must get automatically unlocked if failed/killed within.
let x = ~RWlock();
let x2 = ~x.clone();
let x2 = (*x).clone();

let result: result::Result<(),()> = do task::try || {
do lock_rwlock_in_mode(x2, mode1) {
do lock_rwlock_in_mode(&x2, mode1) {
fail!();
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ext/pipes/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub fn analyze(proto: protocol, _cx: @ext_ctxt) {
debug!("colive iteration %?", i);
let mut new_colive = ~[];
for colive.eachi |i, this_colive| {
let mut result = ~this_colive.clone();
let mut result = this_colive.clone();
let this = proto.get_state_by_id(i);
for this_colive.ones |j| {
let next = proto.get_state_by_id(j);
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-pass/alt-value-binding-in-guard-3291.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
fn foo(x: Option<~int>, b: bool) -> int {
match x {
None => { 1 }
Some(copy x) if b => { *x }
Some(ref x) if b => { *x.clone() }
Some(_) => { 0 }
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-pass/assignability-trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub fn main() {
// Call a method
for x.iterate() |y| { fail_unless!(x[*y] == *y); }
// Call a parameterized function
fail_unless!(length(copy x) == vec::len(x));
fail_unless!(length(x.clone()) == vec::len(x));
// Call a parameterized function, with type arguments that require
// a borrow
fail_unless!(length::<int, &[int]>(x) == vec::len(x));
Expand Down
4 changes: 2 additions & 2 deletions src/test/run-pass/block-iter-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ fn iter_vec<T>(v: ~[T], f: &fn(&T)) { for v.each |x| { f(x); } }
pub fn main() {
let v = ~[1, 2, 3, 4, 5];
let mut sum = 0;
iter_vec(copy v, |i| {
iter_vec(copy v, |j| {
iter_vec(v.clone(), |i| {
iter_vec(v.clone(), |j| {
sum += *i * *j;
});
});
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-pass/block-vec-map2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ pub fn main() {
vec::map2(~[1, 2, 3, 4, 5],
~[true, false, false, true, true],
|i, b| if *b { -(*i) } else { *i } );
error!(copy v);
error!(v.clone());
fail_unless!((v == ~[-1, 2, 3, -4, -5]));
}
2 changes: 1 addition & 1 deletion src/test/run-pass/borrowck-borrow-from-expr-block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn borrow(x: &int, f: &fn(x: &int)) {
}

fn test1(x: @~int) {
do borrow(copy *x) |p| {
do borrow(&*x.clone()) |p| {
let x_a = ptr::addr_of(&(**x));
fail_unless!((x_a as uint) != ptr::to_uint(p));
fail_unless!(unsafe{*x_a} == *p);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
fn switcher(x: Option<@int>) {
let mut x = x;
match x {
Some(@y) => { copy y; x = None; }
Some(@y) => { y.clone(); x = None; }
None => { }
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-pass/class-exports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ mod kitty {
}

pub impl cat {
fn get_name(&self) -> ~str { copy self.name }
fn get_name(&self) -> ~str { self.name.clone() }
}

pub fn cat(in_name: ~str) -> cat {
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-pass/class-implement-traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ fn cat(in_x : uint, in_y : int, in_name: ~str) -> cat {
cat {
meows: in_x,
how_hungry: in_y,
name: copy in_name
name: in_name.clone()
}
}

Expand Down
9 changes: 6 additions & 3 deletions src/test/run-pass/class-separate-impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
// except according to those terms.

// xfail-fast
use core::to_str::*;

struct cat {
priv meows : uint,

Expand Down Expand Up @@ -53,7 +51,12 @@ fn cat(in_x : uint, in_y : int, in_name: ~str) -> cat {
}

impl ToStr for cat {
pure fn to_str(&self) -> ~str { copy self.name }
pure fn to_str(&self) -> ~str {
// FIXME #5384: this unsafe block is to work around purity
unsafe {
self.name.clone()
}
}
}

fn print_out(thing: @ToStr, expected: ~str) {
Expand Down
4 changes: 2 additions & 2 deletions src/test/run-pass/expr-alt-generic-unique1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
// -*- rust -*-
type compare<T> = @fn(~T, ~T) -> bool;

fn test_generic<T:Copy>(expected: ~T, eq: compare<T>) {
fn test_generic<T:Copy+Clone>(expected: ~T, eq: compare<T>) {
let actual: ~T = match true {
true => { copy expected },
true => { expected.clone() },
_ => fail!(~"wat")
};
fail_unless!((eq(expected, actual)));
Expand Down
4 changes: 2 additions & 2 deletions src/test/run-pass/expr-alt-generic-unique2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@

type compare<T> = @fn(T, T) -> bool;

fn test_generic<T:Copy>(expected: T, eq: compare<T>) {
fn test_generic<T:Copy+Clone>(expected: T, eq: compare<T>) {
let actual: T = match true {
true => copy expected,
true => expected.clone(),
_ => fail!(~"wat")
};
fail_unless!((eq(expected, actual)));
Expand Down
Loading