-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
functions implement Copy but not Clone #28229
Comments
Even worse, because fn c<T: Copy>(t: T) -> (T, T) { (t.clone(), t) }
fn f() {}
fn main() {
c(0);
c(f);
}
This (including the ICE) was already reported in #24000, so this looks like a duplicate |
Nominating as this seems relatively serious, but the failure mode is just an ICE then it doesn't seem super super pressing. |
@nikomatsakis: should we make |
We could just add something like the following to the libcore, I think: impl<R> Clone for fn() -> R {
fn clone(&self) -> Self { self }
}
impl<R, A1> Clone for fn(A1) -> R {
fn clone(&self) -> Self { self }
}
impl<R, A1, A2> Clone for fn(A1, A2) -> R {
fn clone(&self) -> Self { self }
}
impl<R, A1, A2, A3> Clone for fn(A1, A2, A3) -> R {
fn clone(&self) -> Self { self }
} We do exactly the same thing for arrays. |
Err, nevermind, that doesn't really do the right thing: that only works for function pointers, not function definitions. |
I’m pretty sure this cannot be done backwards compatibly because such impl would conflict with all the explicit |
@nagisa it should be fine with specialisation. |
It would be fine with lattice impls. Which is a different feature from specialization. Actually, even that wouldn't be backwards-compatible, given that you would need to provide the meet impls (e.g. |
I don't understand what you mean, allowing more specialised impls (i.e. this) is exactly what specialisation is. Anyway nitpicking the exact terminology probably doesn't matter so much here... |
@aturon's specialization RFC - rust-lang/rfcs#1210 - does not allow for overlapping impls in any case. There are also proposals for "lattice impls", which allow overlapping impls as long as there is a meet between every 2 impls. This is not part of the RFC. |
Ah, I was speaking more abstractly, but in fact, @aturon has realised a modification to the RFC that allows cases like this, just hasn't had time to publish. |
On Fri, Sep 04, 2015 at 01:33:13PM -0700, arielb1 wrote:
Possibly. My preferred strategy here would be to leverage |
Variants which include all these proposed in the RFC. |
triage: P-medium We're still working out the preferred way to solve this problem. I tagged T-lang because of the interaction w/ specialization. |
Triage: P-low. ICE is problematic though would be great to fix it. Can anybody mentor? |
@brson fixing this is no small thing, sadly. I had hoped we could address it through specialization but that does not seem to be the case. @arielb1 has been advocating for building the clone impls into the compiler, that might be the most prudent short-term path at least, particularly given that |
@nikomatsakis oh, that would be great. I was only hoping to stop the ICE! |
If |
@nikomatsakis If this is still an issue and you have the time, I would like to look at this. I would be pretty new to Rust and the Compiler though |
@cseale Great! Since writing my last comment, I now have greater hope for being able to fix this through specialization (and hence without modifying the compiler), but those plans remain a bit in flux, so I think it's probably best to close this hole in the compiler for the time being. I will try to write up some instructions tomorrow! |
Hi @nikomatsakis, any chance we could take a look at this? 😃 |
@cseale argh, sorry, added to my to-do list for tomorrow =) I think part of my hesitation is that it's going to be potentially a bit messy to hack this in, and if specialization can solve it that will be much nicer (and of course it's been this long...). But let me glance over code tomorrow to try and decide just how invasive it will be. |
@nikomatsakis no problem! if there is another outstanding E-mentor issue involving that compiler maybe I would be better spending my time there? I am just trying to get involved in that part of the codebase |
This makes multiplexers slightly more ergonomic. Due to rust-lang/rust#28229 (functions implement Copy but not Clone) it's not currently possible to do with closures yet but it's better than nothing
I've written a fix for this locally, however I wonder how it would be integrated in the compiler (if it is).
I cannot merge the two steps since the compiler would not understand the attribute |
@scalexm Use Basically you slap a |
Generate builtin impls for `Clone` This fixes a long-standing ICE and limitation where some builtin types implement `Copy` but not `Clone` (whereas `Clone` is a super trait of `Copy`). However, this PR has a few side-effects: * `Clone` is now marked as a lang item. * `[T; N]` is now `Clone` if `T: Clone` (currently, only if `T: Copy` and for `N <= 32`). * `fn foo<'a>() where &'a mut (): Clone { }` won't compile anymore because of how bounds for builtin traits are handled (e.g. same thing currently if you replace `Clone` by `Copy` in this example). Of course this function is unusable anyway, an error would pop as soon as it is called. Hence, I'm wondering wether this PR would need an RFC... Also, cc-ing @nikomatsakis, @arielb1. Related issues: #28229, #24000.
manual impl was a workaround for rust-lang#28229.
This compiles
but this does not (playground)
The only difference is the bounds on T. The Copy trait requires that the Clone trait is also implemented, so I believe both of these should compile.
The text was updated successfully, but these errors were encountered: