Unnamed repository; edit this file 'description' to name the repository.
Fix destructuring assignments not introducing moves
| -rw-r--r-- | crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs | 3 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/closure_captures.rs | 37 |
2 files changed, 39 insertions, 1 deletions
diff --git a/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs b/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs index 34f9508e76..d8a8cceee6 100644 --- a/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs +++ b/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs @@ -1016,8 +1016,9 @@ impl<'a, 'b, 'db, D: Delegate<'db>> ExprUseVisitor<'a, 'b, 'db, D> { } } Pat::Expr(expr) => { - // Destructuring assignment. this.mutate_expr(expr)?; + // Destructuring assignment moves + this.consume_or_copy(place); } Pat::Or(_) | Pat::Box { .. } diff --git a/crates/hir-ty/src/tests/closure_captures.rs b/crates/hir-ty/src/tests/closure_captures.rs index 3942a7ae27..bf0e60cf21 100644 --- a/crates/hir-ty/src/tests/closure_captures.rs +++ b/crates/hir-ty/src/tests/closure_captures.rs @@ -617,3 +617,40 @@ fn foo(foo: &Foo) { expect!["102..126;85..88;114..117 ByRef(Immutable) *foo &'<erased> Foo"], ); } + +#[test] +fn method_call_field_access_regression() { + check_closure_captures( + r#" +//- minicore:copy, fn +struct NonCopy; + +struct Wrapper { + field: NonCopy, +} + +impl Wrapper { + fn wrapped(&self) -> NonCopy { + NonCopy + } +} + +pub struct Wrapper2 { + field1: NonCopy, + field2: NonCopy, +} + +fn fun(wrapper: Wrapper) { + pub fn update<T>(_: impl FnOnce(&mut T)) { + todo!() + } + + update::<Wrapper2>(|this| { + this.field1 = wrapper.wrapped(); + this.field2 = wrapper.field; + }); +} + "#, + expect!["319..411;206..213;350..357,391..398 ByValue wrapper Wrapper"], + ); +} |