-
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
"the trait Clone
is not implemented for the type fn(&mut Foo, …)
#24000
Comments
I think the best plan for fixing this is specialization, which would allow us to add a low-priority, overridable impl like: impl<T:Copy> Clone for T { .. } |
This is likely a more general problem for types where the compiler itself determines they are |
@Florob more accurately, it is a problem for those cases where we don't (and can't, atm) have complete |
(but I guess that's more or less the same thing as what you wrote, on second thought.) |
Note that the lack of
error: internal compiler error: Encountered error |
@dgrunwald oh, that's... not very good at all! that kind of ups the urgency of finding a good fix for this. |
(though if we have to hack up something to fix the ICE, we could.) |
This problem also applies to fixed sized arrays, e.g. @dgrunwald's example fn test<T: Copy>(x: T) { x.clone(); }
fn main() { test([0; 1000]); }
|
Ran into this just now helping someone with cloneable iterators. Turns out that you can't clone a |
I ran into this again with code like this: let runs: Vec<Range<usize>> = /* ... */;
let mut iter = runs.iter().flat_map(Clone::clone); When trying to clone
let runs: Vec<Range<usize>> = /* ... */;
fn id(x: Range<usize>) -> Range<usize> { x }
let mut iter = runs.iter().cloned().flat_map(id as fn(x: Range<usize>) -> Range<usize>); It’d be helpful if closure types were |
@DanielKeep @SimonSapin You can clone a Map iterator with a fn pointer, but not a Filter.. :-( This since Best solution is probably @nikomatsakis idea of somehow providing Clone for everything that's Copy. |
Minimal reproduction here:
|
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.
Correct me if im wrong, but shouldn't this being fixed mean that the following code should compile? type Function = Fn(i32) -> i32;
#[derive(Clone)]
struct FunctionContainer {
function: Box<Function>
}
fn main() {
} As you can see here, the code does not compile on the latest nightly version https://play.rust-lang.org/?gist=dd13b37b72d2a3a9cc48229654c18036&version=nightly |
@TheZoq2, note the difference between lowercase fn and Fn in Rust. The latter is a closure trait. Cloning trait objects is by the way a much trickier subject. |
Ah, that makes sense, thank you for the clarification |
Wait no, #44490 is about closure types (which are anonymous). For your code to compile with trait objects I think it’d also need to mention a |
@SimonSapin This is a relatively common Rust question and the solutions are typically more involved than that - you basically need to have a |
@RogueGod What do you mean by “this”? This issue is about function pointer types specifically. A reduced test case is: #[derive(Clone)]
struct Foo(fn(&mut u32)); Or: fn foo(function_pointer: fn(&mut u32)) {
Clone::clone(&function_pointer);
} Both of these examples would cause |
@TheZoq2 This does compile. #[derive(Clone)]
struct FunctionContainer {
function: Box<dyn Function>,
}
trait Function: Fn(i32) -> i32 {
fn clone_boxed(&self) -> Box<dyn Function>;
}
impl<T> Function for T
where
T: 'static + Clone + Fn(i32) -> i32,
{
fn clone_boxed(&self) -> Box<dyn Function> {
Box::new(self.clone())
}
}
impl Clone for Box<dyn Function> {
fn clone(&self) -> Self {
self.clone_boxed()
}
} |
Upgrading rust-encoding to Rust beta, I hit this error message:
Shouldn’t this
fn
type implementClone
? It seems to implementCopy
.The text was updated successfully, but these errors were encountered: