From 9274703ac44cf92e708e5468e8fca28e5db64612 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sun, 22 Sep 2024 06:07:27 +0300 Subject: [PATCH 1/2] Properly account for mutable references when postfix-completing consuming completions (e.g. `call`) --- .../ide-completion/src/completions/postfix.rs | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/crates/ide-completion/src/completions/postfix.rs b/crates/ide-completion/src/completions/postfix.rs index a632f148936d..2ede799c8756 100644 --- a/crates/ide-completion/src/completions/postfix.rs +++ b/crates/ide-completion/src/completions/postfix.rs @@ -302,9 +302,10 @@ fn include_references(initial_element: &ast::Expr) -> (ast::Expr, ast::Expr) { while let Some(parent_ref_element) = resulting_element.syntax().parent().and_then(ast::RefExpr::cast) { + let exclusive = parent_ref_element.mut_token().is_some(); resulting_element = ast::Expr::from(parent_ref_element); - new_element_opt = make::expr_ref(new_element_opt, false); + new_element_opt = make::expr_ref(new_element_opt, exclusive); } } else { // If we do not find any ref expressions, restore @@ -855,4 +856,23 @@ fn test() { expect![[r#""#]], ); } + + #[test] + fn mut_ref_consuming() { + check_edit( + "call", + r#" +fn main() { + let mut x = &mut 2; + &mut x.$0; +} +"#, + r#" +fn main() { + let mut x = &mut 2; + ${1}(&mut x); +} +"#, + ); + } } From 7c015944b32dc046683d05fec18f733627d51473 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sun, 22 Sep 2024 06:07:49 +0300 Subject: [PATCH 2/2] Include dereferences in consuming postfix completions (e.g. `call`) --- .../ide-completion/src/completions/postfix.rs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/crates/ide-completion/src/completions/postfix.rs b/crates/ide-completion/src/completions/postfix.rs index 2ede799c8756..d3579fd8cc6e 100644 --- a/crates/ide-completion/src/completions/postfix.rs +++ b/crates/ide-completion/src/completions/postfix.rs @@ -294,6 +294,18 @@ fn include_references(initial_element: &ast::Expr) -> (ast::Expr, ast::Expr) { let mut new_element_opt = initial_element.clone(); + while let Some(parent_deref_element) = + resulting_element.syntax().parent().and_then(ast::PrefixExpr::cast) + { + if parent_deref_element.op_kind() != Some(ast::UnaryOp::Deref) { + break; + } + + resulting_element = ast::Expr::from(parent_deref_element); + + new_element_opt = make::expr_prefix(syntax::T![*], new_element_opt); + } + if let Some(first_ref_expr) = resulting_element.syntax().parent().and_then(ast::RefExpr::cast) { if let Some(expr) = first_ref_expr.expr() { resulting_element = expr; @@ -872,6 +884,25 @@ fn main() { let mut x = &mut 2; ${1}(&mut x); } +"#, + ); + } + + #[test] + fn deref_consuming() { + check_edit( + "call", + r#" +fn main() { + let mut x = &mut 2; + &mut *x.$0; +} +"#, + r#" +fn main() { + let mut x = &mut 2; + ${1}(&mut *x); +} "#, ); }