Skip to content

Closure returned as impl FnOnce incorrectly borrows captured used-by-value iff it is Copy #100905

Closed
@CAD97

Description

@CAD97

Given the following code: [playground] (with the other cases as well)

#[derive(Clone, Copy)]
pub struct Unit;

fn returns(it: Unit) -> impl FnOnce() -> Unit {
    || it
}

The current output is:

error[E0373]: closure may outlive the current function, but it borrows `it`, which is owned by the current function
 --> src/lib.rs:5:5
  |
5 |     || it
  |     ^^ -- `it` is borrowed here
  |     |
  |     may outlive borrowed value `it`
  |
note: closure is returned here
 --> src/lib.rs:5:5
  |
5 |     || it
  |     ^^^^^
help: to force the closure to take ownership of `it` (and any other referenced variables), use the `move` keyword
  |
5 |     move || it
  |     ++++

If you remove the Copy implementation, then this compiles without error.

APIT also compiles without error, but TAIT also causes an error.

Without Copy
#[derive(Clone)]
pub struct Unit;

fn returns(it: Unit) -> impl FnOnce() -> Unit {
    || it
}

APIT
#[derive(Clone, Copy)]
pub struct Unit;

fn apit(it: Unit) {
    fn takes(_: impl FnOnce() -> Unit) {}
    takes(|| Unit)
}

TAIT
#[derive(Clone, Copy)]
pub struct Unit;

fn tait(it: Unit) {
    type F = impl FnOnce() -> Unit;
    let f: F = || it;
}

I checked, and this has been the case since RPIT was first stabilized.

@rustbot label +A-impl-trait

Technically, this makes adding Copy to a type a breaking change 🙃

I expected to see this happen: explanation

Instead, this happened: explanation

Meta

rustc version: 1.65.0-nightly (2022-08-16 86c6ebe)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.AsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-bugCategory: This is a bug.WG-asyncWorking group: Async & await

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions