Skip to content

Should const FnMut require const FnOnce? #148251

@theemathas

Description

@theemathas

I am opening this issue so we don't forget to make a decision on this before stabilizing const traits.

It is unclear whether const FnMut should require const FnOnce or not. In other words, should the super trait bound on FnMut be const trait FnMut: FnOnce, or const trait FnMut: [const] FnOnce?

It is clear that const Fn should require const FnMut, which is enforced in #147939. However, the situation is less clear whether const FnMut should require const FnOnce. For example:

fn only_const_fn_mut() -> impl FnOnce() + const FnMut() {
    let mut thing = NonConstDestruct;  // Doesn't implement const Destruct
    const move || do_something(&mut thing)
}

In this hypothetical code, assuming that const closures were to be implemented, it makes some sense for the closure to implement const FnMut (since all it's doing is mutating thing), but the closure cannot implement FnOnce, since calling it via FnOnce would require running the destructor of thing. This use case can only be supported if const FnMut does not require const FnOnce.

On the other hand, if const FnMut were to not require const FnOnce, then user code would be unable to directly pass a const FnMut closure to a function that expects a const FnOnce without some workaround (e.g., wrapping the closure in another closure). This seems annoying and confusing to users. This is a point in favor of making const FnMut require const FnOnce.

See also some prior discussion on zulip.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-closuresArea: Closures (`|…| { … }`)C-discussionCategory: Discussion or questions that doesn't represent real issues.F-const_closures`#![feature(const_closures)]`F-const_trait_impl`#![feature(const_trait_impl)]`T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions