Unnamed repository; edit this file 'description' to name the repository.
fix: Closure capturing for let exprs, again
Shoyu Vanilla 10 months ago
parent f14bf95 · commit f3eb22e
-rw-r--r--crates/hir-ty/src/infer/closure.rs7
-rw-r--r--crates/hir-ty/src/tests/closure_captures.rs28
-rw-r--r--crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs18
3 files changed, 48 insertions, 5 deletions
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs
index 65a273cdf8..c3029bf2b5 100644
--- a/crates/hir-ty/src/infer/closure.rs
+++ b/crates/hir-ty/src/infer/closure.rs
@@ -1229,10 +1229,11 @@ impl InferenceContext<'_> {
self.select_from_expr(*expr);
}
}
- Expr::Let { pat: _, expr } => {
+ Expr::Let { pat, expr } => {
self.walk_expr(*expr);
- let place = self.place_of_expr(*expr);
- self.ref_expr(*expr, place);
+ if let Some(place) = self.place_of_expr(*expr) {
+ self.consume_with_pat(place, *pat);
+ }
}
Expr::UnaryOp { expr, op: _ }
| Expr::Array(Array::Repeat { initializer: expr, repeat: _ })
diff --git a/crates/hir-ty/src/tests/closure_captures.rs b/crates/hir-ty/src/tests/closure_captures.rs
index 7fb981752d..dbc68eeba1 100644
--- a/crates/hir-ty/src/tests/closure_captures.rs
+++ b/crates/hir-ty/src/tests/closure_captures.rs
@@ -446,7 +446,7 @@ fn main() {
}
#[test]
-fn let_binding_is_a_ref_capture() {
+fn let_binding_is_a_ref_capture_in_ref_binding() {
check_closure_captures(
r#"
//- minicore:copy
@@ -454,12 +454,36 @@ struct S;
fn main() {
let mut s = S;
let s_ref = &mut s;
+ let mut s2 = S;
+ let s_ref2 = &mut s2;
let closure = || {
if let ref cb = s_ref {
+ } else if let ref mut cb = s_ref2 {
}
};
}
"#,
- expect!["83..135;49..54;112..117 ByRef(Shared) s_ref &'? &'? mut S"],
+ expect![[r#"
+ 129..225;49..54;149..155 ByRef(Shared) s_ref &'? &'? mut S
+ 129..225;93..99;188..198 ByRef(Mut { kind: Default }) s_ref2 &'? mut &'? mut S"#]],
+ );
+}
+
+#[test]
+fn let_binding_is_a_value_capture_in_binding() {
+ check_closure_captures(
+ r#"
+//- minicore:copy, option
+struct Box(i32);
+fn main() {
+ let b = Some(Box(0));
+ let closure = || {
+ if let Some(b) = b {
+ let _move = b;
+ }
+ };
+}
+"#,
+ expect!["73..149;37..38;103..104 ByValue b Option<Box>"],
);
}
diff --git a/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs b/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs
index 0928262d22..1e80d02926 100644
--- a/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs
+++ b/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs
@@ -239,4 +239,22 @@ impl S {
"#,
)
}
+
+ #[test]
+ fn regression_20155() {
+ check_diagnostics(
+ r#"
+//- minicore: copy, option
+struct Box(i32);
+fn test() {
+ let b = Some(Box(0));
+ || {
+ if let Some(b) = b {
+ let _move = b;
+ }
+ };
+}
+"#,
+ )
+ }
}