Skip to content

Implement Clone for more arrays #30130

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

Merged
merged 3 commits into from
Dec 5, 2015
Merged

Implement Clone for more arrays #30130

merged 3 commits into from
Dec 5, 2015

Conversation

tbu-
Copy link
Contributor

@tbu- tbu- commented Dec 1, 2015

[breaking-change]

@rust-highfive
Copy link
Contributor

r? @nikomatsakis

(rust_highfive has picked a reviewer for you, use r? to override)

@tbu- tbu- mentioned this pull request Dec 1, 2015
@@ -85,6 +85,7 @@
#![feature(unwind_attributes)]
#![cfg_attr(stage0, feature(simd))]
#![cfg_attr(not(stage0), feature(repr_simd, platform_intrinsics))]
#![feature(slice_patterns)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've historically had a lot of codegen issues with this in the past, so I'm somewhat wary to enable this to implement this for now. Can this be implemented without this feature?

@tbu-
Copy link
Contributor Author

tbu- commented Dec 1, 2015

Making empty array Copy requires a compiler change because the compiler will give you an error if you try to implement Copy for an array.

This was possible to implement without using slice patterns, but only in a weird way.

r? @alexcrichton

@tbu- tbu- changed the title Implement Clone for [T; 0] to [T; 32] if T: Clone Implement Clone for more arrays and make empty array Copyable Dec 1, 2015
impl<T: Clone> Clone for [T; $n] {
fn clone(&self) -> [T; $n] {
let temp = [&self[$i], $(&self[$idx]),*];
[temp[$i].clone(), $(temp[$idx].clone()),*]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can make this a bit simpler:

            fn clone(&self) -> [T; $n] {
                [temp[$i-$i].clone(), $(temp[$i-$idx].clone()),*] 
            }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, thank you. For some reason I couldn't figure out how to reverse the indices.

@bluss bluss added the relnotes Marks issues that should be documented in the release notes of the next release. label Dec 2, 2015
@bluss
Copy link
Member

bluss commented Dec 2, 2015

It's a breaking change, but only for relatively broken code. It's simply that copyable elements have .clone() called now too, so it's a user-observable change.

I think we can say that any code that breaks was already buggy (due to clone and copy not being equivalent).

Example:

#[derive(Copy)]
struct Foo;

impl Clone for Foo { fn clone(&self) -> Self { panic!() } }

// Will panic in new code, used to be “fine.”
[Foo].clone(); 

Edit / Note behaviourial changes are not actutally covered by our API evolution RFC. Anyway, this comment is mostly due diligence: We need to understand each behaviour change when we appove of it.

@alexcrichton
Copy link
Member

Hm upon reflection I'm a little less cure about special casing a 0-length array, for example do we special case that for Send and Sync as well (e.g. other marker traits), I'd want to make sure we stay consistent there.

Also yeah technically this could break code, but I can't imagine anyone actually relying on that in practice. You're likely to have way more surprising results than this if your Clone is that different than Copy.

@tbu-
Copy link
Contributor Author

tbu- commented Dec 4, 2015

@alexcrichton Should I split that out into a different PR again?

@alexcrichton
Copy link
Member

Hm yeah, sorry for the roundabout there!

@tbu-
Copy link
Contributor Author

tbu- commented Dec 4, 2015

@alexcrichton Split it up again.

@tbu- tbu- changed the title Implement Clone for more arrays and make empty array Copyable Implement Clone for more arrays Dec 4, 2015
@alexcrichton
Copy link
Member

@bors: r+ 6dff9d0

@bors
Copy link
Collaborator

bors commented Dec 4, 2015

⌛ Testing commit 6dff9d0 with merge 62eb243...

@bors
Copy link
Collaborator

bors commented Dec 4, 2015

💔 Test failed - auto-mac-64-opt

@alexcrichton
Copy link
Member

@bors: retry

@bors
Copy link
Collaborator

bors commented Dec 4, 2015

⌛ Testing commit 6dff9d0 with merge e22a64e...

bors added a commit that referenced this pull request Dec 4, 2015
@netvl
Copy link
Contributor

netvl commented Dec 6, 2015

I'm not sure why, but it seems that this PR broke compilation of structures like

#[derive(Copy, Clone)]
struct Array {
    arr: [[u8; 256]; 4]
}

that is, structures with Copy, Clone derive attribute which contain a short array of longer arrays. Somehow, previously this code did compile. One of affected libraries seems to be rust-crypto (DaGenix/rust-crypto#335).

@bluss
Copy link
Member

bluss commented Dec 6, 2015

@netvl That's a clear case that we didn't think about :( The reason is that [_; 256] does not implement Clone.

bluss added a commit to bluss/rust that referenced this pull request Dec 6, 2015
This reverts commit e22a64e.

This caused a regression such that types like `[[u8; 256]; 4]`
no longer implemented Clone. This previously worked due to Clone
for `[T; N]` (N in 0 to 32) being implemented for T: Copy.

Due to fixed size arrays not implementing Clone for sizes above 32,
the new implementation requiring T: Clone would not allow
`[[u8; 256]; 4]` to be Clone.
bors added a commit that referenced this pull request Dec 7, 2015
Revert "PR #30130 Implement `Clone` for more arrays"

This reverts commit e22a64e.

This caused a regression such that types like `[[u8; 256]; 4]`
no longer implemented Clone. This previously worked due to Clone
for `[T; N]` (N in 0 to 32) being implemented for T: Copy.

Due to fixed size arrays not implementing Clone for sizes above 32,
the new implementation requiring T: Clone would not allow
`[[u8; 256]; 4]` to be Clone.

Fixes #30244

Due to changing back, this is technically a [breaking-change],
albeit for a behavior that existed for a very short time.
@bluss bluss removed the relnotes Marks issues that should be documented in the release notes of the next release. label Dec 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants