Skip to content

Copy not implemented on returned closures #68307

@zakcutner

Description

@zakcutner

I am exploring how the Copy trait is implicitly added to closures as in this RFC. As a simple example, let's say I create a function foo which takes a Copy closure.

fn foo(f: impl Fn(i32) + Copy) {
    f(10);
}

Although in this case f does not need to be Copy, this is just to simplify the example, let's pretend that it really does. Now I create a function bar which returns the same type of closure that foo accepts.

fn bar() -> impl Fn(i32) {
    |x: i32| {
        println!("{}", x);
    }
}

From my reading of the RFC, the returned closure should implicitly implement Copy. However, if I try to call foo with the result from bar, the compiler gives me an error because I do not explicitly implement Copy on the closure returned by bar.

foo(bar());
    ^^^^^ the trait `std::marker::Copy` is not implemented for `impl std::ops::Fn<(i32,)>`

Whilst I could change the signature of bar to return impl Fn(i32) + Copy let's assume that I do not have control over this function as it is defined in another crate. Interestingly, if I wrap the whole thing in another (and pointless!) closure, it works 👀

foo(|x: i32| bar()(x));

I have seen this exact pattern come up when using combinator libraries (nom for instance), and the second working solution is pretty frustrating as the outer closure has no purpose.

  1. Is this the intended behaviour of the Rust compiler? Surely this is a bug that it can only infer Copy on local closures and not those returned by functions?

  2. Is there something simple I'm missing; maybe I can write this in another way to avoid this issue? For this, please assume that I cannot edit foo or bar as this is based on real examples where combinators I use are defined by other crates.

Thank you! 😄

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-closuresArea: Closures (`|…| { … }`)A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.C-feature-requestCategory: A feature request, i.e: not implemented / a PR.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions