Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/ide-assists/src/handlers/generate_function.rs51
1 files changed, 50 insertions, 1 deletions
diff --git a/crates/ide-assists/src/handlers/generate_function.rs b/crates/ide-assists/src/handlers/generate_function.rs
index ded3b0f5ac..f62eccaf19 100644
--- a/crates/ide-assists/src/handlers/generate_function.rs
+++ b/crates/ide-assists/src/handlers/generate_function.rs
@@ -147,7 +147,16 @@ fn gen_method(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
return None;
}
- let (impl_, file) = get_adt_source(ctx, &adt, fn_name.text().as_str())?;
+ let enclosing_impl = ctx.find_node_at_offset::<ast::Impl>();
+ let cursor_impl = enclosing_impl.filter(|impl_| {
+ ctx.sema.to_def(impl_).map_or(false, |def| def.self_ty(ctx.sema.db).as_adt() == Some(adt))
+ });
+
+ let (impl_, file) = if let Some(impl_) = cursor_impl {
+ (Some(impl_), ctx.vfs_file_id())
+ } else {
+ get_adt_source(ctx, &adt, fn_name.text().as_str())?
+ };
let target = get_method_target(ctx, &impl_, &adt)?;
let function_builder = FunctionBuilder::from_method_call(
@@ -3206,4 +3215,44 @@ fn bar(arg: impl Fn(_) -> bool) {
"#,
);
}
+ #[test]
+ fn generate_method_uses_current_impl_block() {
+ check_assist(
+ generate_function,
+ r"
+struct Foo;
+
+impl Foo {
+ fn new() -> Self {
+ Foo
+ }
+}
+
+impl Foo {
+ fn method1(&self) {
+ self.method2$0(42)
+ }
+}
+",
+ r"
+struct Foo;
+
+impl Foo {
+ fn new() -> Self {
+ Foo
+ }
+}
+
+impl Foo {
+ fn method1(&self) {
+ self.method2(42)
+ }
+
+ fn method2(&self, arg: i32) {
+ ${0:todo!()}
+ }
+}
+",
+ )
+ }
}