From 4e169c46cf60cb43c6d15c5e473a67cdd83d4769 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sat, 4 Jul 2026 17:13:55 +0800 Subject: [PATCH] fix: do not convert mut ref arg for generate_function Considering like `Option::get_or_insert` `Vec::push`, this is not suitable for conversion Example --- ```rust struct S; fn foo() { $0bar(&mut Some(S)) } ``` **Before this PR** ```rust fn bar(s: Option<&S>) { ${0:todo!()} } ``` **After this PR** ```rust fn bar(s: &mut Option) { ${0:todo!()} } ``` --- .../src/handlers/generate_function.rs | 52 ++++++++++++++++++- crates/ide-assists/src/utils.rs | 1 + 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/crates/ide-assists/src/handlers/generate_function.rs b/crates/ide-assists/src/handlers/generate_function.rs index 14dd4061e72f..c5fb84bb6dce 100644 --- a/crates/ide-assists/src/handlers/generate_function.rs +++ b/crates/ide-assists/src/handlers/generate_function.rs @@ -1269,7 +1269,7 @@ fn fn_arg_type( generic_params.extend(ty.generic_params(ctx.db())); - if ty.is_reference() || ty.is_mutable_reference() { + if ty.is_reference() && !ty.is_mutable_reference() { let famous_defs = &FamousDefs(&ctx.sema, ctx.sema.scope(fn_arg.syntax())?.krate()); convert_reference_type(ty.strip_references(), ctx.db(), famous_defs) .map(|conversion| conversion.convert_type(ctx.db(), target_module).to_string()) @@ -3331,6 +3331,56 @@ fn bar(arg: impl Fn(_) -> bool) { "#, ); } + + #[test] + fn convert_reference_type() { + check_assist( + generate_function, + r#" +//- minicore: option +struct S; +fn foo() { + $0bar(&Some(S)) +} + "#, + r#" +struct S; +fn foo() { + bar(&Some(S)) +} + +fn bar(s: Option<&S>) { + ${0:todo!()} +} + "#, + ); + } + + #[test] + fn not_convert_mutable_reference_type() { + // Considering like Option::get_or_insert, this is not suitable for conversion + check_assist( + generate_function, + r#" +//- minicore: option +struct S; +fn foo() { + $0bar(&mut Some(S)) +} + "#, + r#" +struct S; +fn foo() { + bar(&mut Some(S)) +} + +fn bar(s: &mut Option) { + ${0:todo!()} +} + "#, + ); + } + #[test] fn generate_method_uses_current_impl_block() { check_assist( diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs index 2c4fb5f405a7..842c16038e3d 100644 --- a/crates/ide-assists/src/utils.rs +++ b/crates/ide-assists/src/utils.rs @@ -847,6 +847,7 @@ impl<'db> ReferenceConversion<'db> { // FIXME: It should return a new hir::Type, but currently constructing new types is too cumbersome // and all users of this function operate on string type names, so they can do the conversion // itself themselves. +/// NOTE: This does not apply to mutable references pub(crate) fn convert_reference_type<'db>( ty: hir::Type<'db>, db: &'db RootDatabase,