Skip to content
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

fn pointer type is not Clone when containing a parameter with an unspecified lifetime #20468

Closed
samfoo opened this issue Jan 3, 2015 · 5 comments
Labels
A-trait-system Area: Trait system A-type-system Area: Type system C-bug Category: This is a bug.

Comments

@samfoo
Copy link

samfoo commented Jan 3, 2015

The following snippet fails to compile.

#[deriving(Clone)]
enum Thing {
    Func(fn(&str) -> String)
}

#[allow(unused_variables)]
fn a(b: &str) -> String {
    "a".to_string()
}

#[allow(unused_variables)]
fn main() {
    let f = Thing::Func(a);

    println!("Good to go!");
}

Yielding the error...

<anon>:3:10: 3:28 error: the trait `core::clone::Clone` is not implemented for the type `fn(&str) -> collections::string::String`
<anon>:3     Func(fn(&str) -> String)
                  ^~~~~~~~~~~~~~~~~~
note: in expansion of #[deriving]
<anon>:1:1: 1:19 note: expansion site

However, it works when the argument reference is given a lifetime specifier (as below).

#[deriving(Clone)]
enum Thing {
    Func(fn(&'static str) -> String)
}

#[allow(unused_variables)]
fn a(b: &'static str) -> String {
    "a".to_string()
}

#[allow(unused_variables)]
fn main() {
    let f = Thing::Func(a);

    println!("Good to go!");
}
Good to go!

Structs/enums cloneability should not rely on the lifetime of a bare function's arguments, since the argument's lifetime is relative to the function, not the struct.

Compiler version details:

$ rustc --version --verbose
rustc 0.13.0-nightly (10d99a973 2014-12-31 21:01:42 +0000)
binary: rustc
commit-hash: 10d99a973498c5a1be6ba318210751efc1c2cf61
commit-date: 2014-12-31 21:01:42 +0000
host: x86_64-apple-darwin
release: 0.13.0-nightly
@fengsp
Copy link

fengsp commented Jan 5, 2015

I have got the same error, is this a bug or what? I just can not clone any function that takes a reference.

@kmcallister kmcallister changed the title Unable to copy enum/struct with bare function that accepts a reference as an argument bare fn types fail to be Clone depending on parameter lifetimes Jan 14, 2015
@kmcallister kmcallister added A-type-system Area: Type system A-trait-system Area: Trait system labels Jan 14, 2015
@gaudecker
Copy link

I ran into the same error.

@blaenk
Copy link
Contributor

blaenk commented Mar 1, 2015

Note that if you contain types in the fn signature that are from your own crate, you can provide an explicit implementation yourself as a workaround. That doesn't solve this in the general case though, such as in the example in the first post, since neither &str nor String are from your own crate.

@steveklabnik
Copy link
Member

Traige: new code:

#[derive(Clone)]
enum Thing {
    Func(fn(&str) -> String)
}

#[allow(unused_variables)]
fn a(b: &str) -> String {
    "a".to_string()
}

#[allow(unused_variables)]
fn main() {
    let f = Thing::Func(a);

    println!("Good to go!");
}

@Mark-Simulacrum Mark-Simulacrum changed the title bare fn types fail to be Clone depending on parameter lifetimes fn pointer type is not Clone when containing a parameter with a unspecified lifetime May 2, 2017
@Mark-Simulacrum Mark-Simulacrum changed the title fn pointer type is not Clone when containing a parameter with a unspecified lifetime fn pointer type is not Clone when containing a parameter with an unspecified lifetime May 2, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 22, 2017
@nikomatsakis
Copy link
Contributor

Fixed now, thanks to @scalexm's PR for #44490. I believe there exist enough tests, so just going to close.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-trait-system Area: Trait system A-type-system Area: Type system C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

8 participants