Skip to content

fix: fix the capture behavior of if let in closures#154210

Open
Embers-of-the-Fire wants to merge 5 commits into
rust-lang:mainfrom
Embers-of-the-Fire:feat/if-let-no-full-capture
Open

fix: fix the capture behavior of if let in closures#154210
Embers-of-the-Fire wants to merge 5 commits into
rust-lang:mainfrom
Embers-of-the-Fire:feat/if-let-no-full-capture

Conversation

@Embers-of-the-Fire
Copy link
Copy Markdown
Contributor

@Embers-of-the-Fire Embers-of-the-Fire commented Mar 22, 2026

View all comments

Closes #153982.
TL;DR This patch adds the missing capture behavior change for if let statements introduced in RFC 2229.

This patch converts

self.walk_local(init, pat, None, || self.borrow_expr(init, BorrowKind::Immutable))?;

into

self.walk_local(init, pat, None, || Ok(()))?;

so that if let now behaves like let.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 22, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Mar 22, 2026

r? @mati865

rustbot has assigned @mati865.
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 69 candidates
  • Random selection from 13 candidates

@meithecatte
Copy link
Copy Markdown
Contributor

Could you add a test case that's a bit more like #153982, so that there's also a field that doesn't get captured in the first place?

@Kivooeo
Copy link
Copy Markdown
Member

Kivooeo commented Mar 22, 2026

cc @Nadrieril

@theemathas theemathas added T-lang Relevant to the language team needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. needs-crater This change needs a crater run to check for possible breakage in the ecosystem. labels Mar 22, 2026
Copy link
Copy Markdown
Contributor

@meithecatte meithecatte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, this is technically a breaking change, much like #138961, right? It'd be nice to have a proof-of-concept test on which the borrow checker will start erroring, at which point we'd probably wanna do a crater run...

View changes since this review

Comment thread compiler/rustc_hir_typeck/src/expr_use_visitor.rs Outdated
@Kivooeo
Copy link
Copy Markdown
Member

Kivooeo commented Mar 22, 2026

@bors try

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Mar 22, 2026
…e, r=<try>

fix: fix the capture behavior of `if let` in closures
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented Mar 22, 2026

☀️ Try build successful (CI)
Build commit: dec9417 (dec9417b8611e34e787a3e4c37686b5131f9e5c5, parent: 562dee4820c458d823175268e41601d4c060588a)

@Kivooeo
Copy link
Copy Markdown
Member

Kivooeo commented Mar 22, 2026

I'm wondering which mode we should run crater in. Would cargo check be sufficient, or should we use build or build and test instead?

@Embers-of-the-Fire
Copy link
Copy Markdown
Contributor Author

Would cargo check be sufficient

AFAIK check should be sufficient since this patch modifies something rather high in the compiler, and in theory, strong dependencies on the size of closures shouldn't be very common. The most likely result is that we may break the unit tests for some of the lower level libraries, but it’s unlikely that this will affect functionality.

@meithecatte
Copy link
Copy Markdown
Contributor

Since this PR changes the drop order in some cases, it is technically conceivable that some code would have an observable change in behavior after this PR gets merged. It is also technically possible that a crate's test suite would notice this. I would however be extremely surprised if someone has written such code and made a test suite good enough to be able to detect this – previous experience with crater runs for similar adjustments confirms this.

If it was my call to make, I'd run a check run and assume that in the exceedingly unlikely case where someone does depend on this, it'll get caught by the full crater run for the beta.

But my call to make it is not.

@theemathas
Copy link
Copy Markdown
Contributor

It can technically change run time behavior by changing drop order. I think that's kind of unlikely to be relied on though.

@Kivooeo
Copy link
Copy Markdown
Member

Kivooeo commented Mar 22, 2026

Based on the discussion above, I'm going with just check.

@craterbot run mode=check-only

@craterbot
Copy link
Copy Markdown
Collaborator

👌 Experiment pr-154210 created and queued.
🤖 Automatically detected try build dec9417
⚠️ Try build based on commit 66777ad, but latest commit is 4d78fd1. Did you forget to make a new try build?
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 22, 2026
@jieyouxu
Copy link
Copy Markdown
Member

jieyouxu commented Mar 23, 2026

It can technically change run time behavior by changing drop order. I think that's kind of unlikely to be relied on though.

If this can change runtime behavior (ergo, a stable breaking change), then IMO this definitely justifies a full build-and-test not just check-only. I imagine lang would likewise want as much of the full picture as possible on ecosystem impact when making the accept/reject call.

@Nadrieril
Copy link
Copy Markdown
Member

@craterbot cancel

@craterbot
Copy link
Copy Markdown
Collaborator

🗑️ Experiment pr-154210 deleted!

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot removed the S-waiting-on-crater Status: Waiting on a crater run to be completed. label Mar 24, 2026
@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Apr 20, 2026
@Nadrieril
Copy link
Copy Markdown
Member

All the crater regressions I've looked at look unrelated to this PR

@theemathas
Copy link
Copy Markdown
Contributor

theemathas commented Apr 22, 2026

@rustbot labels +I-lang-nominated

I'm unsure if this a T-lang FCP, but nominated just in case.

In edition 2021+, match and let with a pattern can cause partial captures in closures. Previously, if let did not also have this same partial capture behavior. This PR changes if let so that it can cause partial captures in closures in edition 2021+.

@rustbot rustbot added the I-lang-nominated Nominated for discussion during a lang team meeting. label Apr 22, 2026
@traviscross traviscross added I-lang-radar Items that are on lang's radar and will need eventual work or consideration. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang labels Apr 22, 2026
@traviscross
Copy link
Copy Markdown
Contributor

traviscross commented May 6, 2026

This seems to be a correct consistency fix to me. Based on @Nadrieril's report that all the crater regressions he's looked at seem unrelated (thanks for having a look), I propose we do this.

@rfcbot fcp merge lang

@rust-rfcbot
Copy link
Copy Markdown
Collaborator

rust-rfcbot commented May 6, 2026

Team member @traviscross has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns.
See this document for info about what commands tagged team members can give me.

@rust-rfcbot rust-rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels May 6, 2026
@joshtriplett
Copy link
Copy Markdown
Member

Since this is changing exactly what closures capture, is there a test to make sure that this doesn't introduce new UB-detection issues that rhyme with
rust-lang/reference#2121 ? (Not an expert here, just asking for confirmation that it won't introduce new such issues.)

@tmandry
Copy link
Copy Markdown
Member

tmandry commented May 6, 2026

The potential drop order change is a concern, but since we managed to do it in #138961 with match I think if let should be fine.

@rfcbot reviewed

@joshtriplett
Copy link
Copy Markdown
Member

Going to go ahead and check a box on the assumption that #154210 (comment) is already covered; if there's any issue on that front, please do raise a concern.

@rfcbot reviewed

@traviscross
Copy link
Copy Markdown
Contributor

cc @rust-lang/opsem

@traviscross traviscross removed I-lang-nominated Nominated for discussion during a lang team meeting. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang labels May 6, 2026
@rust-rfcbot rust-rfcbot added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. labels May 6, 2026
@rust-rfcbot
Copy link
Copy Markdown
Collaborator

🔔 This is now entering its final comment period, as per the review above. 🔔

@RalfJung
Copy link
Copy Markdown
Member

RalfJung commented May 6, 2026

cc @rust-lang/opsem

This is more a question of how the generated MIR for these patterns looks like, which we're not the experts on... @Nadrieril are there tests we should have to ensure all the intended UB is captured by the generated MIR?

@Nadrieril
Copy link
Copy Markdown
Member

@Nadrieril are there tests we should have to ensure all the intended UB is captured by the generated MIR?

I'm not sure I follow, do you mean Miri tests?

@RalfJung
Copy link
Copy Markdown
Member

RalfJung commented May 7, 2026

Yes.

@Nadrieril
Copy link
Copy Markdown
Member

match and if let will have the same capture behavior after this, so you could duplicate any test with a match inside a closure and turn it into an if let (and/or vice-versa), but if you trust that the capturing and lowering is indeed the same now then you don't have to do anything.

@RalfJung
Copy link
Copy Markdown
Member

RalfJung commented May 7, 2026

Apparently the lowering was not the same before this PR so it may be worth having some sort of smoke test here?

Is there some test where Miri's verdict (UB vs non-UB) changes with this PR due to the changed capture behavior?

@rust-rfcbot rust-rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. to-announce Announce this issue on triage meeting and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels May 16, 2026
@rust-rfcbot
Copy link
Copy Markdown
Collaborator

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

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

Labels

disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. needs-crater This change needs a crater run to check for possible breakage in the ecosystem. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team to-announce Announce this issue on triage meeting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

let and if let have different closure capture behaviors