Skip to content

Mutable closure captures through opaque casts - #160150

Closed
amirHdev wants to merge 1 commit into
rust-lang:mainfrom
amirHdev:fix-opaque-place
Closed

Mutable closure captures through opaque casts#160150
amirHdev wants to merge 1 commit into
rust-lang:mainfrom
amirHdev:fix-opaque-place

Conversation

@amirHdev

@amirHdev amirHdev commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

fixes #160120
Preserve place semantics for opaque projections in closure captures instead of lowering them through ExprKind::Use and ensures mutable captures through TAIT opaque casts are validated by borrowck with both solvers

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 29, 2026
@rust-log-analyzer

This comment has been minimized.

Signed-off-by: Amirhossein Akhlaghpour <m9.akhlaghpoor@gmail.com>
@amirHdev
amirHdev marked this pull request as ready for review July 30, 2026 13:18
@rustbot

rustbot commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Some changes occurred in rustc_ty_utils::consts.rs

cc @BoxyUwU

Some changes occurred in match checking

cc @Nadrieril

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jul 30, 2026
@rustbot

rustbot commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

r? @khyperia

rustbot has assigned @khyperia.
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 74 candidates
  • Random selection from 17 candidates

@khyperia

Copy link
Copy Markdown
Contributor

Would you mind describing a bit why a new THIR ExprKind is needed? This seems like it's a bug with the old solver, the new solver is able to error on this without requiring a new THIR node kind. How is it able to do so? Why is a new node kind needed for the old solver? If there's a good reason, do we want to only create this node kind if the old solver is in use?

@amirHdev

Copy link
Copy Markdown
Contributor Author

@khyperia
I looked for differences between the two solvers
with the old solver capture analysis keeps the base type as the opaque T and records the capture path as
OpaqueCast(Foo) -> Field(0)
with the next solver the base is already resolved to Foo and the capture path is only
Field(0)
The current THIR conversion lowers the old solver OpaqueCast to ExprKind::Use and since Use has value semantics during MIR construction it copies foo into a temporary and borrows temporary.0instead of borrowing foo.0 which is why the old solver misses E0596. the next solver directly borrows foo.0 so borrowck reports the error.
the new THIR node preserves the existing opaque cast as a place operation until MIR where it becomes ProjectionElem::OpaqueCast and keep MutBorrowKind::Default for this case asClosureCapture assumes that the mutation inside the closure will independently produce an error but under the old solver that mutation is lowered through the temporary and no such error is produced. that preserving the place cast alone while retaining ClosureCapture still accepts the program.

I tried replacing the captured place's opaque base type with the hidden type instead but the actual MIR local remains opaque. projecting a field from it without OpaqueCast violates MIR place typing and causes an ICE.
A closure specific side channel could carry the projection directly to MIR but that would require threading additional capture metadata through duplicating place lowering. preserving it as a THIR place expression appears to be the more direct representation

@lcnr

lcnr commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

I feel fairly uncomfortable with changes here and think that OpaqueCast is quite fragile.

The new solver handles this correctly by normalizing opaque types in the defining scope. I think we should keep #160120 as an error with the old solver as properly fixing this requires properly normalizing opaque types which is too large of a change given the impending next-solver stabilization

@amirHdev

amirHdev commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@lcnr that makes sense thanks for clarifying. I’ll close the PR then

@amirHdev amirHdev closed this Aug 3, 2026
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TAIT: ref mut destructuring does not require marking variable as mutable

5 participants