Skip to content

Commit c86aefd

Browse files
committed
feat: extract_struct_from_function_signature
fixed bug where if extracting from function/method in impl and was referenced somewhere else in impl it would break down b/c making the impl mut would happen after the reference was updated
1 parent 4ed8b0b commit c86aefd

File tree

1 file changed

+38
-5
lines changed

1 file changed

+38
-5
lines changed

crates/ide-assists/src/handlers/extract_struct_from_function_signature.rs

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,11 @@ pub(crate) fn extract_struct_from_function_signature(
120120

121121
tracing::info!("extract_struct_from_function_signature: starting edit");
122122
builder.edit_file(ctx.vfs_file_id());
123+
// atl the make muts should generally before any edits happen
123124
let func_mut = builder.make_mut(func.clone());
125+
// if in impl block then put struct before the impl block
126+
let (indent, syntax) = param_list.self_param().and_then(|_|ctx.find_node_at_range::<ast::Impl>() )
127+
.map(|imp|( imp.indent_level(), builder.make_syntax_mut(imp.syntax().clone()))).unwrap_or((func.indent_level(), func_mut.syntax().clone()));
124128
builder.make_mut(param_list.clone());
125129
let used_param_list = used_param_list.into_iter().map(|p| builder.make_mut(p)).collect_vec();
126130
tracing::info!("extract_struct_from_function_signature: editing main file");
@@ -175,12 +179,7 @@ pub(crate) fn extract_struct_from_function_signature(
175179
tracing::info!("extract_struct_from_function_signature: collecting fields");
176180
let def = create_struct_def(name.clone(), &func_mut, &used_param_list, &field_list, generics);
177181
tracing::info!("extract_struct_from_function_signature: creating struct");
178-
179-
// if in impl block then put struct before the impl block
180-
let (indent, syntax) = param_list.self_param().and_then(|_|ctx.find_node_at_range::<ast::Impl>() ).map(|imp|builder.make_mut(imp)).map(|imp|( imp.indent_level(), imp.syntax().clone())).unwrap_or((func.indent_level(), func_mut.syntax().clone()));
181182
let def = def.indent(indent);
182-
183-
184183
ted::insert_all(
185184
ted::Position::before(syntax),
186185
vec![
@@ -850,6 +849,40 @@ impl Foo {
850849
fn foo(&self, FooStruct { j, i, .. }: FooStruct, z:i32) { }
851850
}
852851
852+
fn bar() {
853+
Foo.foo(FooStruct { j: 1, i: 2 }, 3)
854+
}
855+
"#,
856+
);
857+
}
858+
#[test]
859+
fn test_extract_function_signature_in_method_with_reference_in_impl() {
860+
check_assist(
861+
extract_struct_from_function_signature,
862+
r#"
863+
struct Foo
864+
impl Foo {
865+
fn foo(&self, $0j: i32, i: i32$0, z:i32) { }
866+
fn baz(&self) {
867+
self.foo(4, 5, 6)
868+
}
869+
}
870+
871+
fn bar() {
872+
Foo.foo(1, 2, 3)
873+
}
874+
"#,
875+
r#"
876+
struct Foo
877+
struct FooStruct{ j: i32, i: i32 }
878+
879+
impl Foo {
880+
fn foo(&self, FooStruct { j, i, .. }: FooStruct, z:i32) { }
881+
fn baz(&self) {
882+
self.foo(FooStruct { j: 4, i: 5 }, 6)
883+
}
884+
}
885+
853886
fn bar() {
854887
Foo.foo(FooStruct { j: 1, i: 2 }, 3)
855888
}

0 commit comments

Comments
 (0)