Unnamed repository; edit this file 'description' to name the repository.
Fix destructuring assignments not introducing moves
Lukas Wirth 5 weeks ago
parent 57116fa · commit 42160ed
-rw-r--r--crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs3
-rw-r--r--crates/hir-ty/src/tests/closure_captures.rs37
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"],
+ );
+}