Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #15625 - jDomantas:domantas/fix-15623, r=HKalbasi
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.
bors 2023-09-18
parent 9d0ccf0 · parent a961068 · commit 0566644
-rw-r--r--crates/hir-ty/src/infer/closure.rs10
-rw-r--r--crates/hir-ty/src/layout/tests/closure.rs14
-rw-r--r--crates/ide-diagnostics/src/handlers/mutability_errors.rs23
3 files changed, 42 insertions, 5 deletions
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs
index 1f040393f1..13d6b5643a 100644
--- a/crates/hir-ty/src/infer/closure.rs
+++ b/crates/hir-ty/src/infer/closure.rs
@@ -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);
}
diff --git a/crates/hir-ty/src/layout/tests/closure.rs b/crates/hir-ty/src/layout/tests/closure.rs
index 576e7f3fc6..bbe855a14d 100644
--- a/crates/hir-ty/src/layout/tests/closure.rs
+++ b/crates/hir-ty/src/layout/tests/closure.rs
@@ -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
+ }
+ }
+}
diff --git a/crates/ide-diagnostics/src/handlers/mutability_errors.rs b/crates/ide-diagnostics/src/handlers/mutability_errors.rs
index 8976a3de67..d056e5c85c 100644
--- a/crates/ide-diagnostics/src/handlers/mutability_errors.rs
+++ b/crates/ide-diagnostics/src/handlers/mutability_errors.rs
@@ -1173,4 +1173,27 @@ fn f() {
"#,
);
}
+
+ #[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();
+}
+"#,
+ );
+ }
}