From b30c688856fdd24a6c3c0277af4a44ac64edaaeb Mon Sep 17 00:00:00 2001 From: dfireBird Date: Tue, 18 Nov 2025 09:09:17 +0530 Subject: [PATCH 1/3] fix: extract function panics on more than one usage of variable in macro --- .../src/handlers/extract_function.rs | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/crates/ide-assists/src/handlers/extract_function.rs b/crates/ide-assists/src/handlers/extract_function.rs index ef4b977fe524..2a0a3839b358 100644 --- a/crates/ide-assists/src/handlers/extract_function.rs +++ b/crates/ide-assists/src/handlers/extract_function.rs @@ -2060,7 +2060,7 @@ fn fix_param_usages( .filter_map(|reference| path_element_of_reference(syntax, reference)) .map(|expr| tm.make_mut(&expr)); - usages_for_param.push((param, usages.collect())); + usages_for_param.push((param, usages.dedup().collect())); } let res = tm.make_syntax_mut(syntax); @@ -6233,4 +6233,42 @@ fn $0fun_name(a: i32, b: i32) { cov_mark::check!(extract_function_in_braces_is_not_applicable); check_assist_not_applicable(extract_function, r"fn foo(arr: &mut $0[$0i32]) {}"); } + + #[test] + fn issue_20965_panic() { + check_assist( + extract_function, + r#" +//- minicore: fmt +#[derive(Debug)] +struct Foo(&'static str); + +impl Foo { + fn text(&self) -> &str { self.0 } +} + +fn main() { + let s = Foo(""); + $0print!("{}{}", s, s);$0 + let _ = s.text() == ""; +}"#, + r#" +#[derive(Debug)] +struct Foo(&'static str); + +impl Foo { + fn text(&self) -> &str { self.0 } +} + +fn main() { + let s = Foo(""); + fun_name(&s); + let _ = s.text() == ""; +} + +fn $0fun_name(s: &Foo) { + *print!("{}{}", s, s); +}"#, + ); + } } From d24a6319dbd8e84ff90f9bc19f1316e23875fbcf Mon Sep 17 00:00:00 2001 From: dfireBird Date: Tue, 18 Nov 2025 09:09:32 +0530 Subject: [PATCH 2/3] fix: allow equality expressions in parsing of format_args --- .../src/handlers/extract_function.rs | 22 +++++++++++++++++++ crates/parser/src/grammar/expressions/atom.rs | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/crates/ide-assists/src/handlers/extract_function.rs b/crates/ide-assists/src/handlers/extract_function.rs index 2a0a3839b358..9af76eb23b9a 100644 --- a/crates/ide-assists/src/handlers/extract_function.rs +++ b/crates/ide-assists/src/handlers/extract_function.rs @@ -6268,6 +6268,28 @@ fn main() { fn $0fun_name(s: &Foo) { *print!("{}{}", s, s); +}"#, + ); + } + + #[test] + fn parameter_is_added_used_in_eq_expression_in_macro() { + check_assist( + extract_function, + r#" +//- minicore: fmt +fn foo() { + let v = 123; + $0print!("{v:?}{}", v == 123);$0 +}"#, + r#" +fn foo() { + let v = 123; + fun_name(v); +} + +fn $0fun_name(v: i32) { + print!("{v:?}{}", v == 123); }"#, ); } diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs index cde62e03238a..ab1830930854 100644 --- a/crates/parser/src/grammar/expressions/atom.rs +++ b/crates/parser/src/grammar/expressions/atom.rs @@ -283,7 +283,7 @@ fn builtin_expr(p: &mut Parser<'_>) -> Option { if p.eat(T![,]) { while !p.at(EOF) && !p.at(T![')']) { let m = p.start(); - if p.at(IDENT) && p.nth_at(1, T![=]) { + if p.at(IDENT) && p.nth_at(1, T![=]) && !p.nth_at(2, T![=]) { name(p); p.bump(T![=]); } From 9fe16a60025ff6520b17b97372daf6ebd774df2c Mon Sep 17 00:00:00 2001 From: dfireBird Date: Thu, 20 Nov 2025 11:15:26 +0530 Subject: [PATCH 3/3] fix: use unique instead of dedup --- crates/ide-assists/src/handlers/extract_function.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ide-assists/src/handlers/extract_function.rs b/crates/ide-assists/src/handlers/extract_function.rs index 9af76eb23b9a..44d020a1b46c 100644 --- a/crates/ide-assists/src/handlers/extract_function.rs +++ b/crates/ide-assists/src/handlers/extract_function.rs @@ -2060,7 +2060,7 @@ fn fix_param_usages( .filter_map(|reference| path_element_of_reference(syntax, reference)) .map(|expr| tm.make_mut(&expr)); - usages_for_param.push((param, usages.dedup().collect())); + usages_for_param.push((param, usages.unique().collect())); } let res = tm.make_syntax_mut(syntax);