3

This code (also on play)

use std::sync::Arc;

struct Foo {
    x: isize, // Something complex in actual code, implements Drop
}

#[derive(Clone)]
struct Good {
    a: Option<Arc<Foo>>,
    b: Option<Arc<Foo>>,
    c: Option<Arc<Foo>>,
}

#[derive(Clone)]
struct Bad {
    x: [Option<Arc<Foo>>; 3],
}

fn main() {
    println!("See?");
}

fails for Bad with

<anon>:16:5: 16:29 error: the trait `core::marker::Copy` is not implemented for the type `alloc::arc::Arc<Foo>` [E0277]
<anon>:16     x: [Option<Arc<Foo>>; 3],
              ^~~~~~~~~~~~~~~~~~~~~~~~
<anon>:14:10: 14:15 note: in expansion of #[derive_Clone]

but it has no problem with Good.

  • Why is this and,
  • is there any workaround? I am not exactly keen on handling 12 independent fields.
Jan Hudec
  • 73,652
  • 13
  • 125
  • 172

1 Answers1

4

The issue is in the implementation of the Clone trait:

impl<T> Clone for [T; 4] where T: Copy

That makes the real question: why do we require Copy to clone an array? That implementation says:

fn clone(&self) -> [T; $N] {
    *self
}

So currently, a clone of an array is simply a bit-for-bit copy of the source array. A deeper why may be forthcoming from someone more knowledgeable.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • 2
    More important question, should it be considered a bug (incomplete feature)? – Jan Hudec Mar 17 '15 at 21:26
  • Off-hand I wouldn't know how to automate the implementation . The code would have to be `[self[0].clone(), self[1].clone(), ..., self[N-1].clone()]` which is kind of hard to generate with macros. –  Mar 17 '15 at 22:53
  • 1
    @delnan : I think it's possible to do something out of this : http://is.gd/CQAIDd – Levans Mar 17 '15 at 23:29
  • 1
    @Levans Clever! I never thought it impossible, but I'm pleasantly surprised that it's so simple. Well, for certain values of "simple". Of course, that's completely unsafe for `A` that aren't fixed-size arrays, but it would be private anyway. –  Mar 17 '15 at 23:42
  • @JanHudec: The implementations of traits for arrays and tuples are quite limited today due to the lack of support for *value generic parameters* and *variadic generics* respectively. As a result there are "hacks" (generally macro abuses) to implement the traits for a small number of arities... so I would not be surprised if the implementation as it is was simply a quick attempt at moving on and not a fully thought out solution. So... a WIP. I would encourage you to raise a bug, and even better provide a patch; it could be a nice to have for 1.0! – Matthieu M. Mar 18 '15 at 10:38