Skip to content

Commit

Permalink
Auto merge of #15625 - jDomantas:domantas/fix-15623, r=HKalbasi
Browse files Browse the repository at this point in the history
fix: Don't skip closure captures after let-else

As I understand that `return` was left there by accident. It caused capture analysis to skip the rest of the block after a let-else, and then missed captures caused incorrect results in borrowck, closure hints, layout calculation, etc.

Fixes #15623

I didn't understand why I using the example from #15623 as-is doesn't work - I don't get the warnings unless I remove the `call_me()` call, even on the same commit as my own RA version which does show those warnings.
  • Loading branch information
bors committed Sep 17, 2023
2 parents 9d0ccf0 + a961068 commit 0566644
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 5 deletions.
10 changes: 5 additions & 5 deletions crates/hir-ty/src/infer/closure.rs
Expand Up @@ -469,13 +469,13 @@ impl InferenceContext<'_> {
Statement::Let { pat, type_ref: _, initializer, else_branch } => {
if let Some(else_branch) = else_branch {
self.consume_expr(*else_branch);
if let Some(initializer) = initializer {
self.consume_expr(*initializer);
}
return;
}
if let Some(initializer) = initializer {
self.walk_expr(*initializer);
if else_branch.is_some() {
self.consume_expr(*initializer);
} else {
self.walk_expr(*initializer);
}
if let Some(place) = self.place_of_expr(*initializer) {
self.consume_with_pat(place, *pat);
}
Expand Down
14 changes: 14 additions & 0 deletions crates/hir-ty/src/layout/tests/closure.rs
Expand Up @@ -255,3 +255,17 @@ fn ellipsis_pattern() {
}
}
}

#[test]
fn regression_15623() {
size_and_align_expr! {
let a = 2;
let b = 3;
let c = 5;
move || {
let 0 = a else { return b; };
let y = c;
y
}
}
}
23 changes: 23 additions & 0 deletions crates/ide-diagnostics/src/handlers/mutability_errors.rs
Expand Up @@ -1170,6 +1170,29 @@ fn f() {
loop {}
for _ in 0..2 {}
}
"#,
);
}

#[test]
fn regression_15623() {
check_diagnostics(
r#"
//- minicore: fn
struct Foo;
impl Foo {
fn needs_mut(&mut self) {}
}
fn foo(mut foo: Foo) {
let mut call_me = || {
let 0 = 1 else { return };
foo.needs_mut();
};
call_me();
}
"#,
);
}
Expand Down

0 comments on commit 0566644

Please sign in to comment.