Skip to content

Reform feature(ergonomic_clones) - #165111

Open
Jules-Bertholet wants to merge 4 commits into
rust-lang:mainfrom
Jules-Bertholet:yeet-use-closure
Open

Jules-Bertholet wants to merge 4 commits into
rust-lang:mainfrom
Jules-Bertholet:yeet-use-closure

Conversation

@Jules-Bertholet

@Jules-Bertholet Jules-Bertholet commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Tracking issue: #132290

It seems like the mood in the lang team is that they are no longer motivated to champion this feature in its current form: #165060 (comment)

I still like it, though. I believe that, with some tweaks, it can serve as a useful complement to move expressions. This PR is my proposal to the lang team to pick this feature up and reform it for continued experimentation.

Changes in this PR

  • use || closures and async use {} blocks are no longer a thing.
  • .use aborts on panic, instead of triggering UB.
  • $expr.use requires $expr's type to implement Copy or UseCloned.
  • .use in a normal, non-move closure now has special capturing behavior. To elaborate:

Within a closure, .use on a captured place results in a special by-use capture mode. Captures with this mode are cloned both when the closure is created, as well as every time the closure is run. In other words, || x.use is essentially equivalent to || move(x.clone()).clone(). This allows the closure to implement Fn() without borrowing from the stack frame of its parent.

The clone on closure construction happens only once, even if the capture is .used several times within the closure body. For example, || { x.use; x.use } clones only once on construction, and twice each time the closure is run. (The naïve desugaring in terms of move expressions would clone twice on construction.)

The by-use capture mode is considered to have the lowest priority among all other capture modes. For example, the following closures do not clone on construction: || { x.use; x }, || { x.use; &x }.

By-use capturing also supports edition 2021 precise capturing. For example:

struct Foo<'a> {
    field: &'a (bool, i32),
}

fn foo(f: Foo) {
    // This closure captures `foo.field.0` once by value.
    // (N.B.: The naïve `move` expressions desugaring would capture twice)
    let closure = || {
        let a = foo.field.0.use;
        let b = foo.field.0.use;
    }
}

Fixes #141916, fixes #141952, fixes #164902,

@rustbot label F-ergonomic_clones A-closures A-panic T-lang I-lang-nominated

@rustbot

rustbot commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator

The parser was modified, potentially altering the grammar of (stable) Rust
which would be a breaking change.

cc @fmease

miri is developed in its own repository. If the Miri part of this change can be broken out, consider making this change to rust-lang/miri instead. However, if Miri needs adjusting for rustc changes, just ignore this message.

cc @rust-lang/miri

rust-analyzer is developed in its own repository. If possible, consider making this change to rust-lang/rust-analyzer instead.

cc @rust-lang/rust-analyzer

clippy is developed in its own repository. If possible, consider making this change to rust-lang/rust-clippy instead.

cc @rust-lang/clippy

rustfmt is developed in its own repository. If possible, consider making this change to rust-lang/rustfmt instead.

cc @rust-lang/rustfmt

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-rust-analyzer Relevant to the rust-analyzer team, which will review and decide on the PR/issue. T-rustfmt Relevant to the rustfmt team, which will review and decide on the PR/issue. labels Oct 29, 2026
@rustbot

rustbot commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator

r? @beetrees

rustbot has assigned @beetrees.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 77 candidates
  • Random selection from 22 candidates

@rustbot rustbot added A-closures Area: Closures (`|…| { … }`) A-panic Area: Panicking machinery F-ergonomic_clones `#![feature(ergonomic_clones)]` I-lang-nominated Nominated for discussion during a lang team meeting. T-lang Relevant to the language team labels Oct 29, 2026
@beetrees beetrees added S-waiting-on-t-lang Status: Awaiting decision from T-lang and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 29, 2026
@rustbot rustbot removed the T-rust-analyzer Relevant to the rust-analyzer team, which will review and decide on the PR/issue. label Oct 29, 2026
@RalfJung

Copy link
Copy Markdown
Member

.use aborts on panic, instead of triggering UB.

I continue to think that this is inconsistent with the rest of the language and should not be done just one feature at a time. If we are okay with turning unwinds into aborts, we should systematically think about where that should be done. But there's a notable portion of Rust users that really strongly opposes this so it needs wider discussion.

@traviscross traviscross added I-lang-radar Items that are on lang's radar and will need eventual work or consideration. P-lang-drag-2 Lang team prioritization drag level 2.https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang. labels Oct 29, 2026
@Jules-Bertholet

Jules-Bertholet commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor Author

This is not a final proposal, I'm open to changing my mind on everything including the abort-on-panic part. That being said, I think the "inconsistency" with e.g. drop actually makes sense. Drop can flush I/O, close network connections, and do all sorts of complicated stuff that risks a panic. UseCloned's contract requires not doing any of that, not even a heap allocation. That's why the case for aborting is particularly strong for this specific feature IMO.

@RalfJung

Copy link
Copy Markdown
Member

This is not a final proposal,

Right. So usually this would be then a discussion between you and the t-lang champion for this feature. Given that Niko stepped back as a champion, I guess the next step would be to find a new champion, if there's still interest in the lang team for this feature.

@rustbot rustbot added the T-rust-analyzer Relevant to the rust-analyzer team, which will review and decide on the PR/issue. label Oct 30, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-closures Area: Closures (`|…| { … }`) A-panic Area: Panicking machinery F-ergonomic_clones `#![feature(ergonomic_clones)]` I-lang-nominated Nominated for discussion during a lang team meeting. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. P-lang-drag-2 Lang team prioritization drag level 2.https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang. S-waiting-on-t-lang Status: Awaiting decision from T-lang T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team T-libs Relevant to the library team, which will review and decide on the PR/issue. T-rust-analyzer Relevant to the rust-analyzer team, which will review and decide on the PR/issue. T-rustfmt Relevant to the rustfmt team, which will review and decide on the PR/issue.

Projects

None yet

6 participants