diff options
| author | Lukas Wirth <me@lukaswirth.dev> | 2025-06-19 04:47:50 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-19 04:47:50 +0000 |
| commit | 58d4b993318af197f752f5335ddfa320cc6414b6 (patch) | |
| tree | 10fc9589df2c2a55d2d89065c7afcbd41678fc8d | |
| parent | e7971e4a9b815968139b977ece9a76b62bf4fb10 (diff) | |
| parent | 70f376d308c6d144c897be988427a13c9a276b00 (diff) | |
| download | rust-58d4b993318af197f752f5335ddfa320cc6414b6.tar.gz rust-58d4b993318af197f752f5335ddfa320cc6414b6.zip | |
Merge pull request #20039 from ShoyuVanilla/let-bind-ref-capt
fix: Closure capturing for let exprs
3 files changed, 43 insertions, 1 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs index d1432cacf8d..b756bb859d3 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs @@ -1230,11 +1230,15 @@ impl InferenceContext<'_> { self.select_from_expr(*expr); } } + Expr::Let { pat: _, expr } => { + self.walk_expr(*expr); + let place = self.place_of_expr(*expr); + self.ref_expr(*expr, place); + } Expr::UnaryOp { expr, op: _ } | Expr::Array(Array::Repeat { initializer: expr, repeat: _ }) | Expr::Await { expr } | Expr::Loop { body: expr, label: _ } - | Expr::Let { pat: _, expr } | Expr::Box { expr } | Expr::Cast { expr, type_ref: _ } => { self.consume_expr(*expr); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs index 88d21be81ea..7fb981752de 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs @@ -444,3 +444,22 @@ fn main() { expect!["99..165;49..54;120..121,133..134 ByRef(Mut { kind: Default }) a &'? mut A"], ); } + +#[test] +fn let_binding_is_a_ref_capture() { + check_closure_captures( + r#" +//- minicore:copy +struct S; +fn main() { + let mut s = S; + let s_ref = &mut s; + let closure = || { + if let ref cb = s_ref { + } + }; +} +"#, + expect!["83..135;49..54;112..117 ByRef(Shared) s_ref &'? &'? mut S"], + ); +} diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs index 7181d708fe3..0928262d22f 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs @@ -220,4 +220,23 @@ fn test() { "#, ) } + + #[test] + fn regression_18201() { + check_diagnostics( + r#" +//- minicore: copy +struct NotCopy; +struct S(NotCopy); +impl S { + fn f(&mut self) { + || { + if let ref mut _cb = self.0 { + } + }; + } +} +"#, + ) + } } |
