Skip to content

fix: Closure capturing for let exprs #20039

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 19, 2025

Conversation

ShoyuVanilla
Copy link
Member

@ShoyuVanilla ShoyuVanilla commented Jun 18, 2025

Fixes #18201

We have been handling closure captures for let expressions in a wrong way:

Here,

| Expr::Let { pat: _, expr }
| Expr::Box { expr }
| Expr::Cast { expr, type_ref: _ } => {
self.consume_expr(*expr);
}

which ends up as a capture by value if the captured target is not Copy

fn consume_expr(&mut self, expr: ExprId) {
if let Some(place) = self.place_of_expr(expr) {
self.consume_place(place);
}
self.walk_expr(expr);
}
fn consume_place(&mut self, place: HirPlace) {
if self.is_upvar(&place) {
let ty = place.ty(self);
let kind = if self.is_ty_copy(ty) {
CaptureKind::ByRef(BorrowKind::Shared)
} else {
CaptureKind::ByValue
};
self.push_capture(place, kind);
}
}

But rustc handles this as a capture by ref(immutable, in most cases) in the following lines:

https://github.com/rust-lang/rust/blob/6f935a044d1ddeb6160494a6320d008d7c311aef/compiler/rustc_hir_typeck/src/expr_use_visitor.rs#L452-L454
https://github.com/rust-lang/rust/blob/6f935a044d1ddeb6160494a6320d008d7c311aef/compiler/rustc_hir_typeck/src/upvar.rs#L2093-L2114

Of course, rustc's capturing logic is more sophiscated than my modification here and we lack many details of them but at least, this one is at least more precise than the present, I think 😅

I think that we should move our capturing logic closer to that of rustc, but after next-gen solver migration

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 18, 2025
@Veykril Veykril added this pull request to the merge queue Jun 19, 2025
Merged via the queue into rust-lang:master with commit bb1efeb Jun 19, 2025
14 checks passed
@ShoyuVanilla ShoyuVanilla deleted the let-bind-ref-capt branch June 19, 2025 04:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Closure incorrectly tries to move instead of borrow in ref patterns within if let
3 participants