Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #12706 - DorianListens:dscheidt/closure-args, r=DorianListens
fix: Extract Function misses locals used in closures This change fixes #12705. In `FunctionBody::analyze`, we need to search any `ClosureExpr`s we encounter for any `NameRef`s, to ensure they aren't missed.
bors 2022-07-08
parent c419aa9 · parent 603b6fc · commit 2836dd1
-rw-r--r--crates/ide-assists/src/handlers/extract_function.rs30
1 files changed, 30 insertions, 0 deletions
diff --git a/crates/ide-assists/src/handlers/extract_function.rs b/crates/ide-assists/src/handlers/extract_function.rs
index 36c1524f0e..9233c198df 100644
--- a/crates/ide-assists/src/handlers/extract_function.rs
+++ b/crates/ide-assists/src/handlers/extract_function.rs
@@ -699,6 +699,11 @@ impl FunctionBody {
ast::Expr::PathExpr(path_expr) => {
cb(path_expr.path().and_then(|it| it.as_single_name_ref()))
}
+ ast::Expr::ClosureExpr(closure_expr) => {
+ if let Some(body) = closure_expr.body() {
+ body.syntax().descendants().map(ast::NameRef::cast).for_each(|it| cb(it));
+ }
+ }
ast::Expr::MacroExpr(expr) => {
if let Some(tt) = expr.macro_call().and_then(|call| call.token_tree()) {
tt.syntax()
@@ -4845,4 +4850,29 @@ impl Struct {
"#,
);
}
+
+ #[test]
+ fn closure_arguments() {
+ check_assist(
+ extract_function,
+ r#"
+fn parent(factor: i32) {
+ let v = &[1, 2, 3];
+
+ $0v.iter().map(|it| it * factor);$0
+}
+"#,
+ r#"
+fn parent(factor: i32) {
+ let v = &[1, 2, 3];
+
+ fun_name(v, factor);
+}
+
+fn $0fun_name(v: &[i32; 3], factor: i32) {
+ v.iter().map(|it| it * factor);
+}
+"#,
+ );
+ }
}