Skip to content

Cannot impl Clone trait for [T; $N] with T from this crate #25822

New issue

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

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

Already on GitHub? # to your account

Closed
muggenhor opened this issue May 27, 2015 · 2 comments
Closed

Cannot impl Clone trait for [T; $N] with T from this crate #25822

muggenhor opened this issue May 27, 2015 · 2 comments

Comments

@muggenhor
Copy link

Test case:

use std::collections::BitSet;

#[derive(Clone)]
struct Cell {
    content: BitSet,
}

#[derive(Clone)]
struct Field {
    cells: [[Cell; 9]; 9],
}
tst.rs:10:5: 10:26 error: the trait `core::marker::Copy` is not implemented for the type `Cell` [E0277]
tst.rs:10     cells: [[Cell; 9]; 9],
              ^~~~~~~~~~~~~~~~~~~~~
tst.rs:8:10: 8:15 note: in expansion of #[derive_Clone]
tst.rs:8:10: 8:15 note: expansion site
error: aborting due to previous error

Apparently implementing Clone on the "scalar" Cell isn't enough to be able to use it on arrays of Cell, so I try to manually implement it:

use std::collections::BitSet;

#[derive(Clone)]
struct Cell {
    content: BitSet,
}

impl Clone for [Cell; 9] {
    fn clone(&self) -> [Cell; 9] {
        [self[0].clone(), self[1].clone(), self[2].clone(),
         self[3].clone(), self[4].clone(), self[5].clone(),
         self[6].clone(), self[7].clone(), self[8].clone()]
    }
}

impl Clone for [[Cell; 9]; 9] {
    fn clone(&self) -> [[Cell; 9]; 9] {
        [self[0].clone(), self[1].clone(), self[2].clone(),
         self[3].clone(), self[4].clone(), self[5].clone(),
         self[6].clone(), self[7].clone(), self[8].clone()]
    }
}

#[derive(Clone)]
struct Field {
    cells: [[Cell; 9]; 9],
}

That however gets me two problems:

tst.rs:8:1: 14:2 error: the impl does not reference any types defined in this crate; only traits defined in the current crate can be implemented for arbitrary types [E0117]
tst.rs:8 impl Clone for [Cell; 9] {
tst.rs:9     fn clone(&self) -> [Cell; 9] {
tst.rs:10         [self[0].clone(), self[1].clone(), self[2].clone(),
tst.rs:11          self[3].clone(), self[4].clone(), self[5].clone(),
tst.rs:12          self[6].clone(), self[7].clone(), self[8].clone()]
tst.rs:13     }
          ...
tst.rs:16:1: 22:2 error: the impl does not reference any types defined in this crate; only traits defined in the current crate can be implemented for arbitrary types [E0117]
tst.rs:16 impl Clone for [[Cell; 9]; 9] {
tst.rs:17     fn clone(&self) -> [[Cell; 9]; 9] {
tst.rs:18         [self[0].clone(), self[1].clone(), self[2].clone(),
tst.rs:19          self[3].clone(), self[4].clone(), self[5].clone(),
tst.rs:20          self[6].clone(), self[7].clone(), self[8].clone()]
tst.rs:21     }
          ...
tst.rs:16:1: 22:2 error: conflicting implementations for trait `core::clone::Clone` [E0119]
tst.rs:16 impl Clone for [[Cell; 9]; 9] {
tst.rs:17     fn clone(&self) -> [[Cell; 9]; 9] {
tst.rs:18         [self[0].clone(), self[1].clone(), self[2].clone(),
tst.rs:19          self[3].clone(), self[4].clone(), self[5].clone(),
tst.rs:20          self[6].clone(), self[7].clone(), self[8].clone()]
tst.rs:21     }
          ...
tst.rs:16:1: 22:2 note: conflicting implementation in crate `core`
tst.rs:16 impl Clone for [[Cell; 9]; 9] {
tst.rs:17     fn clone(&self) -> [[Cell; 9]; 9] {
tst.rs:18         [self[0].clone(), self[1].clone(), self[2].clone(),
tst.rs:19          self[3].clone(), self[4].clone(), self[5].clone(),
tst.rs:20          self[6].clone(), self[7].clone(), self[8].clone()]
tst.rs:21     }
          ...
error: aborting due to 3 previous errors

The first being that I cannot implement Clone for [T; $N] (where T is either Cell or [Cell; 9] and N is 9). The second refers to a conflict in core, probably that's caused by array.rs and [[T; 9]; 9 somehow implementing the Copy trait (though I don't see how). Part of this can probably be solved by adding a separate implementation of Clone for [T; $N] where T implements the Clone trait (but not the Copy trait). I'm not sure how to prevent the conflict though.

PS This looks similar to #24745 which is mentioned as being caused by #23086 (RFC 1023)

@muggenhor
Copy link
Author

I have the same problem with the Default trait btw: it's also not implementable. But that should definitely be possible to implement correctly for the general case in libcore/array.rs.

muggenhor added a commit to muggenhor/rudoku that referenced this issue May 27, 2015
Do this because implementing it for arrays is prevented by
rust-lang/rust#25822.
@steveklabnik
Copy link
Member

Yes, this is basically the same as that issue. You can't implement a trait you don't own for a type you don't own. So it's not possible to implement standard library traits, like Clone, for standard library types that don't have them already, like [T; N].

In addition, Rust already provides a Cell type, so you may end up with weird shadowing errors.

This issue is going to end up needing rust-lang/rfcs#1038 to be fixed, so I'm giving it a close.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants